# Flex 布局教程

传统的网页布局解决方案都是采用盒状模型,但是在多个盒的存在相互影响或者想要达到比较特殊的布局效果时,盒状模型的布局实现就较为麻烦。

Flex 布局,即 Flexible Box 布局(弹性布局),基于盒状模型提供了更大的灵活性。

😥注意!本篇笔记为 markdown 生成 HTML 文档,内嵌的 CSS 代码在某些编辑器下无法显示。如果显示效果有问题(如 github),建议从个人网站阅读本篇笔记:https://docs.ceynri.cn/notes/css/flex.html (opens new window),阅读体验更佳。


# 属性速览


# 基本概念

使用display: flex;语句,为元素指定 Flex 布局方式。

Flex 默认表现为块级元素,你也可以指定为inline-flex属性,则该元素会表现出内联的性质。

被指定应用 Flex 布局的父元素称为“flex container”(简称容器),而它的子成员则会自动成为“flex item”(简称项目)。

容器存在两根轴:

  • 主轴(main axis)默认为水平方向的轴。
  • 交叉轴(cross axis)默认为垂直方向的轴。

项目沿主轴排列,主轴的方向可以通过设置flex-direction改变,本文默认主轴为水平方向。

一般来说,水平方向的轴的起点为容器的最左边,终点为最右边;垂直方向的轴的起点为容器的最上面,终点为最下面。


# 容器属性

# flex-direction

flex-direction属性决定项目的排列方向(即主轴的方向)。

排列方向
row(默认值)
row-reverse
column
column-reverse
# row
[1] [2] [3]

# row-reverse
[3] [2] [1]

# column
[1]
[2]
[3]

# column-reverse
[3]
[2]
[1]

# flex-wrap

wrap 即换行,该属性指定项目在主轴空间塞不下时如何换行

方式
nowrap(默认值) 不换行,互相压缩一下
wrap 正常的换行
wrap-reverse 反着换行,从交叉轴终点开始往起点方向换行
# nowrap
|[1][2][3][4][5]|
|               |

# wrap
|[ 1 ][ 2 ][ 3 ]|
|[ 4 ][ 5 ]     |

# wrap-reverse
|[ 4 ][ 5 ]     |
|[ 1 ][ 2 ][ 3 ]|

# flex-flow

flex-directionflex-wrap的简写形式。

.box {
  flex-flow: <flex-direction> <flex-wrap>;
}

# justify-content

定义了项目在主轴上的排列分布方式

分布方式
flex-start(默认值) 靠左分布
flex-end 靠右分布
center 集中分布
space-between 两端对齐分布,项目之间间隔相等
space-around 每个项目两侧的间隔相等分布
# flex-start
|[1][2][3]      |

# flex-end
|      [1][2][3]|

# center
|   [1][2][3]   |

# space-between
|[1]   [2]   [3]|

# space-around
| [1]  [2]  [3] |

其中:

  • space-between使最靠边的项目会紧贴容器,项目之间间隔相等;
  • space-around则是每个项目左右边距相等,所以“项目之间的间隔”为“项目与边框之间的间隔”的两倍。

# align-content

定义了多根主轴线之间的排列分布方式

假设交叉轴为从上到下方向:

对齐方式
flex-start 向上靠(向交叉轴起点对齐)
flex-end 向下靠(向交叉轴终点对齐)
center 往中间靠(与交叉轴的中点对齐)
space-between 与交叉轴两端对齐,轴线之间的间隔相等
space-around 每根轴线两侧的间隔都相等
stretch(默认值) 轴线们上下拉伸占满整个交叉轴

注意:如果项目只有一根轴线,该属性不起作用。所以最好应用的元素是定宽的以确保其内的子元素不止一行。

样例:

flex-start

flex-end

center

space-between

space-around

stretch

如果无法看到样例,请访问个人网站阅读本篇笔记 (opens new window)


# align-items

设置项目在交叉轴上的对齐方式(注意与align-content属性的区别)。

对齐方式
flex-start 交叉轴的起点对齐
flex-end 交叉轴的终点对齐
center 交叉轴的中点对齐
baseline 项目的第一行文字的基线对齐
stretch(默认值) 占满整个容器的高度(项目未设置高度或设为 auto)

样例:

1
2
3
4

flex-start

1
2
3
4

flex-end

1
2
3
4

center

1
2
3
4

baseline

1
2
3
4

stretch


# 项目属性

# order

类似于z-index,定义项目的排列顺序。数值越小,排列越靠前,默认为0,可为负值。

# example
|[-1 ] [ 0 ] [ 1 ] [ 1 ] [ 3 ]|
|[ 8 ] [999] [999]            |

# flex-grow

定义项目的放大比例等级,默认值为0(默认如果存在剩余空间,也不放大)。

注意!flex-grow作用的对象是剩余空间,所以当元素分配了一定宽度的时候,不同大小的flex-grow看起来并不按比例分配整个空间。

如果需要几个元素按照你期望的比例占据某个区域,则可以给每个元素设置width: 0,然后再分配flex-grow

# example1
|[ 0 ][ 0 ][ 0 ]      |

# example2
|[  1  ][  1  ][  1  ]|

# example3
|[ 1 ][    2    ][ 1 ]|

# flex-shrink

定义项目的缩小比例等级,默认值为1(默认如果空间不足,该项目将缩小)。

flex-shrink值为0时,即使空间不足该项目也不会缩小。

# example
|[ 1 ][ 1 ][ 1 ][ 1 ]|
|[1][ 0 ][1][1][1][1]|

# flex-basis

定义了在分配多余空间之前,项目占据的主轴空间。默认值为auto(项目的本来大小)。

浏览器根据这个属性,计算主轴是否有多余空间,来决定是否换行。

值可以是单位或者百分数。

width的区别:

flex 布局是有弹性的,你可以设置弹性使得即使主轴空间即使小于项目们加起来的宽度也能通过压缩 width 放入同一行。

flex-basisflex-wrap经常一起使用:

  • 当设置为nowrap时,flex-basis通常没什么作用;
  • 当启用wrap时,你可以允许压缩一定的width而不超过flex-basis值,或者加宽width哪怕原本一行可以塞得下更多项目。

参考:https://blog.csdn.net/lmmxxoo/article/details/83094818 (opens new window)


# flex

flex属性是flex-growflex-shrinkflex-basis的简写。

默认值0 1 auto,后两个属性可选。

该属性有两个快捷值:auto1 1 auto) 和none0 0 auto)。

.item {
  flex: <flex-grow> <flex-shrink> <flex-basis>;
}

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。


# align-self

align-self属性允许单个项目与其他项目有不一样的对齐方式,即“覆盖align-items属性”。

默认值auto,表示继承父元素的align-items属性。如果没有父元素,则等同于stretch

            # example
flex-start  |[a] [bb]     [ddd]|  default
            |                  |
flex-end ---|-------> [c]      |  align-self

# 本文参考

# 其他

阮一峰老师还翻了一篇较为简短的样例讲解(Flexbox 布局的最简单表单 (opens new window)),可以更加直观地了解常用属性的效果。(最后还是应该多动手)


上次更新: 2020/3/1 20:30:40