# Flex 布局教程
传统的网页布局解决方案都是采用盒状模型,但是在多个盒的存在相互影响或者想要达到比较特殊的布局效果时,盒状模型的布局实现就较为麻烦。
Flex 布局,即 Flexible Box 布局(弹性布局),基于盒状模型提供了更大的灵活性。
😥注意!本篇笔记为 markdown 生成 HTML 文档,内嵌的 CSS 代码在某些编辑器下无法显示。如果显示效果有问题(如 github),建议从个人网站阅读本篇笔记:https://docs.ceynri.cn/notes/css/flex.html (opens new window),阅读体验更佳。
# 属性速览
容器
- flex-flow
- flex-direction 排列方向
- flex-wrap 换行方式
- justify-content 水平排列分布
- align-content 垂直排列分布
- align-items 垂直对齐
- flex-flow
项目
- order 顺序
- flex
- flex-grow 占领剩余空间的比例
- flex-shrink 缩小自身时的比例
- flex-basis 界定是否换行的宽度
- align-self 特立独行的对齐方式
# 基本概念
使用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-direction
和flex-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) |
样例:
flex-start
flex-end
center
baseline
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-basis
与flex-wrap
经常一起使用:
- 当设置为
nowrap
时,flex-basis
通常没什么作用; - 当启用
wrap
时,你可以允许压缩一定的width
而不超过flex-basis
值,或者加宽width
哪怕原本一行可以塞得下更多项目。
参考:https://blog.csdn.net/lmmxxoo/article/details/83094818 (opens new window)
# flex
flex
属性是flex-grow
、flex-shrink
和flex-basis
的简写。
默认值0 1 auto
,后两个属性可选。
该属性有两个快捷值:auto
(1 1 auto
) 和none
(0 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)),可以更加直观地了解常用属性的效果。(最后还是应该多动手)