flex布局

网页布局(layout)是 CSS 的一个重点应用。传统的网页布局基于盒状模型,依赖 display + position + float,但它对一些特殊布局不容易实现。

Flex 是 Flexible Box 的缩写,意为“弹性布局”,用来为盒状模型提供最大的灵活性。它可以简便、完整、响应地实现各种页面布局。

指定容器为 Flex 布局。

1
2
3
4
5
6
7
8
9
/* block元素 */
.box {
display: flex;
}

/* 行内元素 */
.box {
display: inline-flex;
}

Flex 布局的子元素的 floatclearvertical-align 等属性将失效。

基本概念

采用 Flex 布局的元素,称为 Flex 容器,它的所有子元素称为 Flex 项目。

容器默认存在两根轴:水平的主轴和垂直的交叉轴。主轴的开始位置叫 main start,结束位置叫 main end;交叉轴的开始位置叫做 cross start,结束位置叫做 cross end

项目默认沿主轴排列。单个项目占据的主轴空间叫做 main size,占据的交叉轴空间叫做 cross size

容器属性

flex-direction

决定主轴方向

  • row:默认。主轴水平,起点在左

    1
    2
    3
    4
    <div class="flex-box">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    </div>
    1
    2
  • row-reverse:主轴水平,起点在右

    1
    2
    3
    4
    <div class="flex-box" style="flex-direction: row-reverse;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    </div>
    1
    2
  • column:主轴垂直,起点在上

    1
    2
    3
    4
    <div class="flex-box" style="flex-direction: column;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    </div>
    1
    2
  • column-reverse:主轴垂直,起点在下

    1
    2
    3
    4
    <div class="flex-box" style="flex-direction: column-reverse;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    </div>
    1
    2

flex-wrap

一条轴排不下,如何换行

  • nowrap:默认。不换行

    1
    2
    3
    4
    5
    6
    7
    <div class="flex-box" style="flex-wrap: nowrap;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    </div>
    1
    2
    3
    4
    5
  • wrap:换行,第一行在上

    1
    2
    3
    4
    5
    6
    7
    <div class="flex-box" style="flex-wrap: wrap;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    </div>
    1
    2
    3
    4
    5
  • wrap-reverse:换行,第一行在下

    1
    2
    3
    4
    5
    6
    7
    <div class="flex-box" style="flex-wrap: wrap-reverse;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    </div>
    1
    2
    3
    4
    5

flex-flow

是 flex-direction 和 flex-wrap 的简写形式

justify-content

决定项目在主轴上的对齐方式

  • flex-start:默认。左对齐

    1
    2
    3
    4
    <div class="flex-box" style="justify-content: flex-start;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    </div>
    1
    2
  • flex-end:右对齐

    1
    2
    3
    4
    <div class="flex-box" style="justify-content: flex-end;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    </div>
    1
    2
  • center:居中

    1
    2
    3
    4
    <div class="flex-box" style="justify-content: center;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    </div>
    1
    2
  • space-between:两端对齐,项目之间的间隔相等

    1
    2
    3
    4
    5
    <div class="flex-box" style="justify-content: space-between;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    </div>
    1
    2
    3
  • space-around:每个项目两侧的间隔相等。所以项目之间的间隔比项目与边框的间隔大一倍

    1
    2
    3
    4
    5
    <div class="flex-box" style="justify-content: space-around;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    </div>
    1
    2
    3

align-items

定义项目在交叉轴上如何对齐

  • flex-start:交叉轴的起点对齐

    1
    2
    3
    4
    5
    <div class="flex-box" style="align-items: flex-start;">
    <div class="flex-item" style="height:20px;">1</div>
    <div class="flex-item" style="height:30px;">2</div>
    <div class="flex-item" style="height:20px;">3</div>
    </div>
    1
    2
    3
  • flex-end:交叉轴的终点对齐

    1
    2
    3
    4
    5
    <div class="flex-box" style="align-items: flex-end;">
    <div class="flex-item" style="height:20px;">1</div>
    <div class="flex-item" style="height:30px;">2</div>
    <div class="flex-item" style="height:20px;">3</div>
    </div>
    1
    2
    3
  • center:交叉轴的中点对齐

    1
    2
    3
    4
    5
    <div class="flex-box" style="align-items: center;">
    <div class="flex-item" style="height:20px;">1</div>
    <div class="flex-item" style="height:30px;">2</div>
    <div class="flex-item" style="height:20px;">3</div>
    </div>
    1
    2
    3
  • baseline:项目的第一行文字的基线对齐

    1
    2
    3
    4
    5
    <div class="flex-box" style="align-items: baseline;">
    <div class="flex-item" style="height:20px;">1</div>
    <div class="flex-item" style="height:40px; line-height:40px; font-size:20px;">2</div>
    <div class="flex-item" style="height:20px;">3</div>
    </div>
    1
    2
    3
  • stretch:默认。如果项目未设置高度或设为auto,将占满整个容器的高度

    1
    2
    3
    4
    5
    <div class="flex-box" style="align-items: stretch;">
    <div class="flex-item" style="height:auto;">1</div>
    <div class="flex-item" style="height:auto;">2</div>
    <div class="flex-item" style="height:auto;">3</div>
    </div>
    1
    2
    3

align-content

定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用

  • flex-start:与交叉轴的起点对齐

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="flex-box" style="flex-wrap: wrap; align-content: flex-start;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    </div>
    1
    2
    3
    4
    5
    6
  • flex-end:与交叉轴的终点对齐

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="flex-box" style="flex-wrap: wrap; align-content: flex-end;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    </div>
    1
    2
    3
    4
    5
    6
  • center:与交叉轴的中点对齐

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="flex-box" style="flex-wrap: wrap; align-content: center;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    </div>
    1
    2
    3
    4
    5
    6
  • space-between:与交叉轴的两端对齐,轴线之间的间隔平均分布

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="flex-box" style="flex-wrap: wrap; align-content: space-between;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    </div>
    1
    2
    3
    4
    5
    6
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="flex-box" style="flex-wrap: wrap; align-content: space-around;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    </div>
    1
    2
    3
    4
    5
    6
  • stretch:默认。轴线占满整个交叉轴

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="flex-box" style="flex-wrap: wrap; align-content: stretch;">
    <div class="flex-item">1</div>
    <div class="flex-item">2</div>
    <div class="flex-item">3</div>
    <div class="flex-item">4</div>
    <div class="flex-item">5</div>
    <div class="flex-item">6</div>
    </div>
    1
    2
    3
    4
    5
    6

项目的属性

order

定义项目的排列顺序。数值越小,排列越靠前。默认为0。

1
2
3
4
5
<div class="flex-box">
<div class="flex-item">1</div>
<div class="flex-item" style="order: -1;">2</div>
<div class="flex-item">3</div>
</div>

1
2
3

flex-grow

定义项目的放大比例,默认为0,即存在剩余空间,也不放大

1
2
3
4
5
<div class="flex-box">
<div class="flex-item">1</div>
<div class="flex-item" style="flex-grow: 1;">2</div>
<div class="flex-item">3</div>
</div>

1
2
3

flex-shrink

定义项目的缩小比例,默认为1,即如果空间不足,该项目将缩小

1
2
3
4
5
6
7
<div class="flex-box">
<div class="flex-item">1</div>
<div class="flex-item" style="flex-shrink: 10;">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
<div class="flex-item">5</div>
</div>

1
2
3
4
5

flex-basis

定义了在分配多余空间之前,项目占据的主轴空间。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

1
2
3
4
5
<div class="flex-box">
<div class="flex-item" style="flex-basis: 30px;">1</div>
<div class="flex-item" style="flex-basis: 20px;">2</div>
<div class="flex-item" style="flex-basis: 10px;">3</div>
</div>

1
2
3

flex

是 flex-grow、flex-shrink 和 flex-basis 的简写,默认值为 0 1 auto。后两个属性可选

align-self

允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

1
2
3
4
5
<div class="flex-box">
<div class="flex-item">1</div>
<div class="flex-item" style="align-self: center;">2</div>
<div class="flex-item" style="align-self: flex-end;">3</div>
</div>

1
2
3

本页DEMO的基础样式及结构

1
2
3
4
5
<div class="flex-box">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.flex-box {
display: flex;
width: 100px;
height: 100px;
border: 1px solid #ddd;
background:#eee;
}
.flex-item {
width: 22px;
height: 22px;
line-height: 22px;
text-align: center;
background: #ccc;
border: 1px solid #333;
}

参考:
Flex 布局教程:语法篇
Flex 布局教程:实例篇