本文主要参考 CSS 伸缩盒布局模组,主要介绍的是应用在元素身上的 flex 属性取值的问题,关于 flex 布局的一些知识可以参考 flex 布局,故本文不会涉及太多
需要注意的是,如果将元素的
display属性设置为flex,那么其就转换为了flex容器,在设为flex容器后,其子元素的float、clear和vertical-align属性都将失效
下面我们就先来简单了解 flex 布局常用的属性和一些取值介绍,其实它主要分为两部分,一个是应用在容器上的属性,另一个是应用在子容器上的属性
容器的属性
有下面六个属性是应用在容器上面的
flex-direction,属性决定主轴的方向(即项目的排列方向)row(默认值),主轴为水平方向,起点在左端row-reverse,主轴为水平方向,起点在右端column,主轴为垂直方向,起点在上沿column-reverse,主轴为垂直方向,起点在下沿
flex-wrap,默认情况下,项目都排在一条线(轴线)上,如果一条轴线排不下,如何换行nowrap(默认),不换行wrap,换行,第一行在上方wrap-reverse,换行,第一行在下方
flex-flow,为flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrapjustify-content,定义了项目在主轴上的对齐方式(左右)flex-start(默认值),左对齐flex-end,右对齐center, 居中space-between,两端对齐,项目之间的间隔都相等space-around,每个项目两侧的间隔相等,所以,项目之间的间隔比项目与边框的间隔大一倍
align-items,定义项目在交叉轴上如何对齐(上下)flex-start,交叉轴的起点对齐flex-end,交叉轴的终点对齐center,交叉轴的中点对齐baseline,项目的第一行文字的基线对齐stretch(默认值),如果项目未设置高度或设为auto,将占满整个容器的高度
align-content,定义了多根轴线的对齐方式如果项目只有一根轴线,无效(意思就是内容分为多行,类似line-height)flex-start,与交叉轴的起点对齐flex-end,与交叉轴的终点对齐center,与交叉轴的中点对齐space-between,与交叉轴两端对齐,轴线之间的间隔平均分布space-around,每根轴线两侧的间隔都相等,所以,轴线之间的间隔比轴线与边框的间隔大一倍stretch(默认值),轴线占满整个交叉轴
元素的属性
有下面六个属性是应用在元素身上的
order,定义项目的排列顺序,数值越小,排列越靠前,默认为0flex-grow,定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大- 如果所有项目的
flex-grow属性都为1,则它们将等分剩余空间(如果有的话) - 如果一个项目的
flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍(类似合并单元格)
- 如果所有项目的
flex-shrink,定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小- 如果所有项目的
flex-shrink属性都为1,当空间不足时,都将等比例缩小 - 如果一个项目的
flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小
- 如果所有项目的
flex-basis,定义了在分配多余空间之前,项目占据的主轴空间- 浏览器根据这个属性,计算主轴是否有多余空间,它的默认值为
auto,即项目的本来大小 - 它可以设为跟
width或height属性一样的值,则项目将占据固定空间
- 浏览器根据这个属性,计算主轴是否有多余空间,它的默认值为
flex,是flex-grow,flex-shrink和flex-basis的简写,默认值为0 1 auto,后两个属性可选align-self,允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性(父级容器指定的排列方式)- 默认值为
auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch - 除了
auto,其他都与align-items属性完全一致
- 默认值为
flex
之前也提到过了,本章主要介绍的就是关于子容器属性上的 flex 取值问题,所以我们下面就来看看这个属性的一些特殊之处,我们都知道,其实子属性身上的 flex 属性是 flex-grow、flex-shrink、flex-basis 的缩写,flex 的默认值是以上三个属性值的组合,假设以上三个属性同样取默认值,则 flex 的默认值是 0 1 auto,如下,是等同的
1 | .item {flex: 222 233 244px;} |
当 flex 取值为 none,则计算值为 0 0 auto,如下是等同的
1 | .item {flex: none;} |
当 flex 取值为 auto,则计算值为 1 1 auto,如下是等同的
1 | .item {flex: auto;} |
当 flex 取值为一个非负数字,则该数字为 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%,如下是等同的
1 | .item {flex: 1;} |
当 flex 取值为一个长度或百分比,则视为 flex-basis 值,flex-grow 取 1,flex-shrink 取 1,有如下等同情况,注意 0% 是一个百分比而不是一个非负数字
1 | .item-1 {flex: 0%;} |
当 flex 取值为两个非负数字,则分别视为 flex-grow 和 flex-shrink 的值,flex-basis 取 0%,如下是等同的
1 | .item {flex: 2 3;} |
当 flex 取值为一个非负数字和一个长度或百分比,则分别视为 flex-grow 和 flex-basis 的值,flex-shrink 取 1,如下是等同的
1 | .item {flex: 2333 3222px;} |
flex-basis 规定的是子元素的基准值,所以是否溢出的计算与此属性息息相关,flex-basis 规定的范围取决于 box-sizing,这里主要讨论以下 flex-basis 的取值情况
auto首先检索该子元素的主尺寸,如果主尺寸不为auto,则使用值采取主尺寸之值,如果也是auto,则使用值为contentcontent指根据该子元素的内容自动布局,有的用户代理没有实现取content值,等效的替代方案是flex-basis和主尺寸都取auto- 百分比 根据其包含块(即伸缩父容器)的主尺寸计算,如果包含块的主尺寸未定义(即父容器的主尺寸取决于子元素),则计算结果和设为
auto一样
实例
下面我们来看一个实例加深一下印象,页面布局如下
1 | <div class="parent"> |
应用的 CSS 如下
1 | .parent { |
最终效果如下

主轴上父容器总尺寸为 600px,那么子元素的总基准值是 0% + auto + 200px = 300px,其中
0%即0宽度auto对应取主尺寸即100px
所以剩余空间为 600px - 300px = 300px,伸缩放大系数之和为 2 + 2 + 1 = 5,那么剩余空间分配如下
item-1和item-2各分配2/5,各得120pxitem-3分配1/5,得60px
所以各项目最终宽度为
item-1 = 0% + 120px = 120pxitem-2 = auto + 120px = 220pxitem-3 = 200px + 60px = 260px
当 item-1 基准值取 0% 的时候,是把该项目视为零尺寸的,故即便声明其尺寸为 9999px,也并没有什么用,形同虚设,而 item-2 基准值取 auto 的时候,根据规则基准值使用值是主尺寸值即 100px,故这 100px 是会用来计算基准值,而不会纳入剩余空间