简单易懂的 Flexbox 布局入门指南。
Flexbox 布局的基本概念
Flexible Box(弹性盒子)模型,通常被称为 Flexbox,是一种流行的一维布局模型,如果学会这个,你就已经可以自己实现当下大部分网站的布局了。下面我们会通过详细谈谈 Flexbox 常用的术语和属性,让你知道弹性盒子应该怎么使用。
来先让我们看看最重要的概念:什么是 Flex 容器?
Flex 容器
弹性盒子的“盒子”指的就是 Flex 容器。通过一系列的设置,这个盒子就可以做到“有弹性”(或者说是响应式的)。理想情况下可以做到,无论怎么拉扯这个盒子,里面的元素的布局都是符合预期的。
创造一个 Flex 容器非常简单,直接设置一个元素的 display
属性为 flex
或者 inline-flex
, 它是一 Flex 容器了。
因为布局模型是一维的,一个容器当然也只能控制一个维度的元素布局。这并不意味着这个布局模型有多差,你可以通过容器的嵌套(也就是令容器的子元素还是容器)来完成复杂的 2D 排版。
一些 Flexbox 的术语
主轴
主轴(main axis),也就是排列子元素的轴。它的起始 / 结束点和方向由 flex-direction
定义。一般情况下,设置了 flex-direction: row;
时,主轴就是一条横轴。
交叉轴
交叉轴(cross axis)垂直于主轴。如果元素的主轴的方向是行的方向,交叉轴指向的就是列的方向。
起始线和终止线
内部元素开始放置的地方和在主轴上放满的地方。主轴的起始/终止线叫 main-start / main-end;交叉轴的起始 / 终止线叫 cross-start / cross-end。
那么 Flexbox 到底可以做些什么?我们通过属性来慢慢了解它。先看看最重要的两个属性,和一个简写属性:
Flex Direction
flex-direction
指定主轴的方向。也就是内部元素排列的方向。初始值是 row
。
取值的解释
-
row
:以行为主轴的方向。准确来说是令主轴方向与文本方向相同,主轴起点和主轴终点与内容方向相同。 -
column
: 以列为主轴的方向。准确来说是令主轴和块轴(也就是 block 排列的方向)相同,主轴起点与主轴终点和书写模式的前后点相同。 -
row-reverse
/column-reverse
: 以行、列为方向反向排布内部元素。准确来说是表现和row
/column
相同,但是置换了主轴起点和主轴终点。
Flex Wrap
flex-wrap
指定容器换行的模式。如果容器的一行被填满了,就会尝试触发换行。溢出的子元素就会像文本的一个个字符一样,被移到下一行开头继续进行排列。初始值是 nowrap
。
取值的解释
-
nowrap
:不允许换行。可能导致 flex 容器溢出。 -
wrap
:正常换行。 -
wrap-reverse
:往反方向换行,内容会从 cross-end 开始,排到 cross-start。
一个方便理解 wrap-reverse 的例子。左边的是 wrap,右边的是 wrap-reverse:
1 2 | 3
3 | 1 2
1 2 3 4- | 10
5 6 7 8 9| 5 6 7 8 9
10 | 1 2 3 4-
Flex Flow
flex-flow
是 flex-direction
和 flex-wrap
的简写。
取值的解释
flex-flow = <'flex-direction'> || <'flex-wrap'>
这里的 || 表示其连接的所有组成元素是可选的,次序任意,但是至少其中一个要出现。例如,可以写成 flex-flow: wrap;
或 flex-flow: nowrap col;
。
下面是一些设置在容器子元素上的属性:
Flex Basis
flex-basis
指定此元素在主轴方向上的初始大小,比主轴方向的大小属性(width
或 height
)具有更高的优先级 。取值要求与 width
的相同。初始值是 auto
。
Flex Grow
flex-grow
指定此元素对容器的剩余空间中想要分配的相对比例。简单来说就是这个值表示元素在容器空间过剩时增长的意愿。取值是个非负数,初始值是 0,表示元素的主方向大小不会被增长。
剩余空间是 容器的大小 - 子元素的大小的和
。如果所有的子元素都有相同的 flex-grow
系数,那么所有的子元素将剩余空间按相同比例分配,否则将根据不同的 flex-grow
定义的比例进行分配。
Flex Shrink
flex-shrink
指定了此元素在 子元素默认大小之和 > 容器大小
的时候才会发生缩小的相对比例。简单来说就是这个值表示元素在空间不足时缩小的意愿。取值是个非负数,初始值是 1。如果设置为 0,元素将不会被缩小。
如果容器在不断变小,且当前元素的 flex-shrink
不为 0,则元素会不断缩小,直至主轴方向大小已经达到最小限制才停止。就比如说主轴方向是行,那么收缩会在到达 min-width 的时候停止。
Flex
flex
是把 grow、shrink 和 basis 的简写属性,在实际开发中用起来比较方便。
语法简记
- 单值语法:
-
flex: <number>;
等价于flex-grow: <number>; flex-shrink: 1; flex-basis: 0;
(注意,之前设置的flex-grow
和flex-shrink
值可能会被覆盖。) flex: <flex-grow: width>;
- 双值语法:
flex: <flex-grow: number> <flex-shrink: number>|<flex-basis: width>;
- 三值语法:
flex: <flex-grow: number> <flex-shrink: number> <flex-basis: width>;
这里的 <属性名: 值类型>
指的是,如果值是这个类型。那么就会被展开到这个属性里面。例如 flex: 1 20px;
会等同于 flex-grow: 1; flex-basis: 20px;
(注意,上面这种表达是不符合CSS 属性值定义语法的,只是为了直观易懂而设计。)
下面是关于一些对齐的属性。
Justify Content
justify-content
可以控制 flex 容器的子元素在主轴上的对齐方式。初始值是 normal
。
取值的解释
以下指的是子元素的行为:
-
start
/end
: 向容器的起始 / 终止边对齐。起始 / 终止边受语言方向的影响。注意,这里是起始 / 终止边而不是flexbox 的起始 / 终止线。左对齐和右对齐通常使用这个属性实现。 -
flex-start
/flex-end
: 向 flex 容器的起始 / 终止线的对齐。 也就是说,这个会受flex-direction: *-reverse;
属性的影响。如果容器不是 flex 容器,则值会视为start
/end
。 -
center
:向每行中间排列。 居中对齐通常使用个属性实现。 -
left
/right
: 向容器的左 / 右边缘对齐。不受语言方向的影响。不推荐使用。 -
space-between
:子元素在每行上间距相同,每行行头行尾元素向两端对齐。每行第一个元素与行首对齐,每行最后一个元素与行尾对齐。 -
space-around
: 与space-between
一样,但是行头尾元素与两端的间距是该行子元素间距之间的一半。 -
space-evenly
: 与space-between
一样,但是行头尾元素与两端的间距与该行子元素间距一致。也就是说每个子元素周围都会有相等大小的空间。 -
normal
:默认状态,和没有设置一样。
Align Items
align-items
可以控制 flex 容器的子元素在交叉轴上的对齐方式。初始值是 normal
。
取值的解释
除了没有 left
/ right
和 space-*
的值以外,其他方面基本与 justify-content
的取值相同。
非常好,你现在已经明白了如何控制 flex 容器子元素的对齐方式了。
通常情况下,如果你要做到将某些元素在容器的两个轴都居中对齐,只需设置 justify-content: center; align-items: center;
就可以了。在这个规范出来以前,要完成这个效果是相当麻烦的。
最后来看看一个控制间距的实用属性:gap
,它是为子元素设置间距的最佳方案 。
Row / Column Gap
row-gap
和 column-gap
分别指定元素行/列的间距。接收一个表示大小的值或者百分比。初始值是 normal
。例如 row-gap: 12px;
设置了行间距为 12px
。
这种说法其实不太好记,将这两个属性理解为 gap-y
和 gap-x
比较好(这个想法来自 Tailwind CSS 的 Gap 章节)。
Gap
gap
可以设置行列之间的间距,是 row-gap
和 column-gap
属性的简写。
取值的解释
<length-percentage> = <length> | <percentage>
-
gap: <a: length-percentage>;
等价于row-gap: <a>; column-gap: <a>
; -
gap: <row-gap: length-percentage> <column-gap: length-percentage>
;
实战
只看可不容易记住东西,建议你去找个地方练练手,把上面说的属性通通试一试。比如 vscode 创建个网页练练手,也可以找一些具有大量相关示例的网站打开浏览器控制台魔改实例。
最后利用这些知识,抄个你喜欢的网站的布局回来,就基本上掌握了。
好了,这其实是作者第一次尝试写文。如果反响还不错,说不定以后我会出更多的文章。
一些声明
本文采用知识共享署名 4.0 国际许可协议进行许可。若有错漏,欢迎纠正~
本文的部分图片是来自 Justify Content - Tailwind CSS 的截屏。
下一篇: Flex 弹性盒型号