提示

本文主要讲解 CSS 中弹性盒子的使用。@ermo

# CSS3 弹性盒子 Flexbox

# 弹性容器 flex container

弹性盒子(Flexbox)可以更加方便快捷的设计响应式页面。相对早期的 float 和 position,不用考虑页面尺寸变化带来的元素塌陷与错误问题。

看一个简单示例:

JavaScript
Python
Java

对应代码为:

<div class="content">
    <div>JavaScript</div>
    <div>Python</div>
    <div>Java</div>
</div>
.content {
    display: flex;
    background-color: pink;
}

.content div {
    margin: 10px;
    padding: 10px;
    background-color: skyblue;
}

上例中 .content 所在的 div 元素成为弹性容器(flex container),内部的3个 div 元素成为弹性子元素(flex items)。

当弹性容器添加 display: flex 样式后,内部子元素会自动横向排列,并且整个弹性容器内部的元素都支持响应式布局。

默认弹性子元素的排列方式是从左到右,也可以通过 direction 设置排列方式。

.content {
    direction: rtl;
    display: flex;
    background-color: pink;
}

direction: rtl 就是将弹性子元素的排列方式设置为从右向做,rtl 就是 right to left。

来看下弹性容器支持的其他样式属性。

# flex-direction

flex-direction 可以设置子元素在容器中的堆叠方向,语法为:

flex-direction: row | row-reverse | column | column-reverse

具体值的含义为:

  • row:横向从左向右排列,左对齐,第一个元素在最左边
  • row-reverse:横向从右向做排列,右对齐,第一个元素在最右边
  • column:纵向从上向下排列,第一个元素在最上边
  • column-reverse:纵向从下向上排列,第一个元素在最下边

实例,默认排列方式:

<div class="flex-container">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</div>
.flex-container {
    display: flex;
    flex-direction: row;
    background-color: grey;
}
.flex-container div {
    padding: 10px;
    margin: 10px;
    background-color: yellow;
}

实例,从右向做排列:

1
2
3
4
.flex-container {
    display: flex;
    flex-direction: row-reverse;
    background-color: grey;
}

.flex-container div {
    padding: 10px;
    margin: 10px;
    background-color: yellow;
}

# justify-content

justify-content 属性用于设置弹性容器内子元素的对齐方式,该属性主要设置子元素沿着内容的主轴线对齐,不能设置纵向对齐。

语法为:

justify-content: flex-start | flex-end | center | space-between | space-around

每个值的含义为:

  • flex-start:子元素在弹性容器的开头对齐,为默认值
  • flex-end:子元素在弹性容器的末端对齐
  • center:子元素在弹性容器的中心对齐
  • space-between:子元素均匀分布到弹性容器一行内,首尾元素没有外边距
  • space-around:子元素均匀分布到弹性容器一行内,两边有一半的间隔空间

实例1,center:

1
2
3
4

实例2,flex-start:

1
2
3
4

实例3,flex-end:

1
2
3
4

实例4,space-between:

1
2
3
4

实例5,space-around:

1
2
3
4

实例代码,每个实例只需替换 justify-content 对应的值即可:

<div class="flex-container-content1">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</div>
.flex-container-content1 {
    display: flex;
    background-color: black;
    justify-content: center;
}
.flex-container-content1 div {
    margin: 10px;
    padding: 10px;
    background-color: skyblue;
}

# align-items

align-items 设置弹性容器内的子元素在容器纵轴上的对齐方式。语法为:

align-items: flex-start | flex-end | center | baseline | stretch

每个值的含义:

  • flex-start:子元素在容器顶部对齐
  • flex-end:子元素在容器底部对齐
  • center:子元素在容器中间对齐
  • baseline:子元素基线对齐
  • stretch:拉伸子元素以填充容器

实例:

<div class="align-ex1">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
</div>
.align-ex1 {
    display: flex;
    height: 200px;
    background-color: pink;
    align-items: stretch;
}
.align-ex1 div {
    margin: 10px;
    width: 100px;
    background-color: skyblue;
    line-height: 175px;
    font-size: 30px;
    text-align: center;
}

# flex-wrap

flex-wrap 用于指定弹性容器内的子元素的换行方式。语法为:

flex-wrap: nowrap | wrap | wrap-reverse

每个值的含义:

  • nowrap:弹性容器为单行,不允许子元素换行,为默认值
  • wrap:弹性容器为多行,子元素溢出部分放置到新的一行
  • wrap-reverse:子元素以相反顺序换行排列

实例,nowrap:

item1
item2
item3
item4
item5

实例,wrap:

item1
item2
item3
item4
item5

实例,wrap-reverse:

item1
item2
item3
item4
item5

对应代码,不同实例只需要切换 flex-wrap 对应的值即可:

<div class="wrap-ex3">
    <div>item1</div>
    <div>item2</div>
    <div>item3</div>
    <div>item4</div>
    <div>item5</div>
</div>
.wrap-ex3 {
    display: flex;
    background-color: grey;
    flex-wrap: wrap-reverse;
}

.wrap-ex3 div {
    background-color: yellow;
    width: 500px;
}

# align-content

align-content 用于修改 flex-wrap 属性的行为。

align-content 只适用于多行的 flex 容器,align-items 适用于单行的 flex 容器。

每个值的含义:

  • flex-start:各行向容器开始位置堆叠
  • flex-end:各行向容器末尾位置堆叠
  • center:各行向容器中间位置堆叠
  • space-between:各行在容器均匀分布,首尾两端没有间距
  • space-around:各行在容器均匀分布,首尾两端有间距
  • stretch:各行将会伸展占用剩余容器的空间,默认值

实例,此时没有使用 align-content 属性:

item1
item2
item3
item4
item5

实例,加上 align-content: center 属性:

item1
item2
item3
item4
item5
再看一个使用 align-items: center,没有 align-content 属性的实例:

item1
item2
item3
item4
item5

不难看出,align-content 的居中是子元素相对整个容器居中,align-items 的居中是子元素相对容器的单行居中。

实例1代码,实例2只需加上 align-content: center,实例3只需加上 align-items: center

<div class="align-content-ex2">
    <div>item1</div>
    <div>item2</div>
    <div>item3</div>
    <div>item4</div>
    <div>item5</div>
</div>
.align-content-ex2 {
    display: flex;
    margin: 30px auto;
    width: 200px;
    height: 200px;
    justify-content: space-between;
    border: 1px solid black;
    flex-wrap: wrap;
    /* align-content: center; */
    /* align-items: center */
}
.align-content-ex2 div {
    width: 50px;
    height: 30px;
    border: 1px solid black;
}

# 子元素 flex-items

子元素也有一些可以使用的属性。

# order

order 用于设置子元素的排列顺序,语法为:

order: number

number 必须为数字,数字越小,排序越靠前。

实例:

<div class="order-ex1">
    <div>1</div>
    <div>2</div>
    <div style="order: 1">3</div>
    <div>4</div>
</div>
.order-ex1 {
    display: flex;
}

输出为:

1243

# align-self

align-self 用于设置子元素在弹性容器内的对齐方式,align-self 会覆盖 align-items 设置的对齐方式。

语法为:

align-self: auto | flex-start | flex-end | center | baseline | stretch

每个值的含义:

  • auto:当前子元素对齐方式为父元素 align-items 设置的值
  • flex-start:纵轴方向顶部对齐
  • flex-end:纵轴方向底部对齐
  • center:纵轴方向中心对齐
  • baseline:基线对齐

实例:

center
flex-start
flex-end
baseline
stretch
normal

对应代码:

        <div class="align-self-ex1">
            <div style="align-self: center;">center</div>
            <div style="align-self: flex-start;">flex-start</div>
            <div style="align-self: flex-end;">flex-end</div>
            <div style="align-self: baseline;">baseline</div>
            <div style="align-self: stretch;">stretch</div>
            <div>normal</div>
        </div>
.align-self-ex1 {
    display: flex;
    width: 400px;
    height: 200px;
    border: 1px solid black;
    margin: 0 auto;
}
.align-self-ex1>div {
    width: 60px;
    height: 60px;
    border: 1px solid black;
    text-align: center;
    margin: 10px;
}

# flex-grow

flex-grow 用于设置当前子元素相对其他子元素增长的值,默认值为0,值必须为数字。

语法为:

flex-grow: number;

实例:

1
2
3
4

代码:

<div class="flex-grow-ex1">
    <div>1</div>
    <div style="flex-grow: 1">2</div>
    <div style="flex-grow: 2">3</div>
    <div style="flex-grow: 4">4</div>
</div>
.flex-grow-ex1 {
    display: flex;
    width: 500px;
    height: 200px;
    border: 1px solid black;
    margin: 0 auto;
}
.flex-grow-ex1 div {
    width: 60px;
    height: 60px;
    border: 1px solid black;
}

# flex-shrink

flex-shrink 用于设置当前子元素相对其他子元素收缩的值,值必须是数字,默认值为0。

在子元素不加 flex-shrink 且父元素不加 flex-wrap: wrap 的情况下,子元素超出父元素宽度,父盒子会自动压缩子盒子的宽度,此时设置了 flex-shrink: 0,当前子元素的宽度不会被压缩。

语法为:

flex-shrink: number;

实例:

1
2
3
4

实例代码。

<div class="flex-shrink-ex1">
    <div>1</div>
    <div>2</div>
    <div class="shrink">3</div>
    <div>4</div>
</div>
.flex-shrink-ex1 {
    display: flex;
    align-items: stretch;
    border: 1px solid black;
    width: 300px;
    margin: 0 auto;
}
.flex-shrink-ex1 div {
    margin: 10px;
    width: 100px;
    border: 1px solid black;
    text-align: center;
}
.flex-shrink-ex1 .shrink {
    flex-shrink: 0
}

# flex-basis

flex-basis 用于设置子元素的初始宽度。

实例,将第三个子元素的初始宽度设置为 60px。

1
2
3
4

实例代码:

<div class="flex-basis-ex1">
    <div>1</div>
    <div>2</div>
    <div style="flex-basis: 60px;">3</div>
    <div>4</div>
</div>
.flex-basis-ex1 {
    display: flex;
    align-items: stretch;
    border: 1px solid black;
    margin: 0 auto;
    width: 300px;
}

.flex-basis-ex1 div {
    width: 20px;
    height: 40px;
    margin: 10px;
    border: 1px solid black;
}

# flex

flex 用于指定子元素如何分配容器空间,就是 flex-growflex-shrinkflex-basis 的简写。

实例,将第三个元素的宽度设置为 50px:

1
2
3
4

实例代码:

<div class="flex-ex1">
    <div>1</div>
    <div>2</div>
    <div class="flex">3</div>
    <div>4</div>
</div>
.flex-ex1 {
    display: flex;
    align-items: stretch;
    border: 1px solid black;
    margin: 0 auto;
    width: 300px;
}

.flex-ex1 div {
    width: 20px;
    height: 40px;
    margin: 10px;
    border: 1px solid black;
}

.flex-ex1 .flex {
    flex: 0 0 50px;
}