9.3.4 弹性子元素的属性
弹性布局盒模型的核心,在于弹性容器中子元素的尺寸是弹性的,容器会根据布局的需要,自动调整子元素的尺寸和顺序,并以最佳方式填充所有可用空间。
当容器中有空白空间时,子元素可以扩展,以占据额外的空白空间;当容器中的空间不足时,子元素可以缩小尺寸,以防止超出容器范围。
在弹性布局盒模型中,浏览器会根据子元素的相关属性,来自动调整子元素的尺寸和顺序。这些属性见表 9‑8:
属性 | 说明 |
---|---|
order | 定义子元素的排列顺序 |
flex-grow | 定义子元素的拉伸因子,当容器空间过剩时,子元素按比例进行拉伸 |
flex-shrink | 定义子元素的收缩因子,当容器空间不足时,子元素按比例进行收缩 |
flex-basis | 定义为子元素分配的默认空间大小 |
flex | 复合属性,定义子元素的拉伸因子、收缩因子、默认空间大小 |
align-self | 定义子元素自身在侧轴方向上的对齐方式 |
order属性
默认情况下,弹性容器中子元素的排列顺序,取决于它们在HTML代码中的排列顺序,先出现的排在前面。
在弹性布局盒模型中,每个子元素有自己独立的 order属性,用来控制子元素的排列顺序,数值小的排在前面。语法格式为:
order: <integer>
order属性的默认值为 0。可以为负值。指定 order 属性后,浏览器将根据 order属性的值,对子元素进行分组,order 值相同的元素属于一组,值小的组排在前面,组内则根据元素在HTML代码中出现的先后顺序,先出现的排在前面。
现在,为三个子元素定义 order属性,取值分别是 2、1、-1,就相当于把所有子元素分为 3 组,每组 1 个元素。CSS代码如下:
.box1 {
order: 2;
background: #7f3ffd;
}
.box2 {
order: 1;
background: #ef39d5;
}
.box3 {
order: -1;
background: #1bb9f1;
}
上述代码运行结果如图 9‑18 所示:

可以看出,box1、box2、box3 的出现顺序与它们在HTML中的定义顺序无关,而是按照 order属性值的大小,数值小的排在前面。
flex-grow属性
flex-grow属性用来定义子元素的拉伸因子,当容器有多余的空间时,浏览器把所有子元素的 flex-grow属性值相加,再根据各自在总值中所占的份额,分配容器的多余空间。语法为:
flex-grow: <number>
flex-grow属性的默认值为 0。支持整数或小数,不允许负值。如果某个子元素没有定义 flex-grow属性,或将 flex-grow属性显式设置为 0,或定义了固定尺寸,则不再为它分配父元素的多余空间。
.father {
width: 600px;
display: flex;
}
.father > div {
width: 100px;
}
.box1 {
flex-grow: 2;
background: #7f3ffd;
}
.box2 {
flex-grow: 1;
background: #ef39d5;
}
.box3 {
background: #1bb9f1;
}
上述代码中,父元素的宽度是 600px,每个子元素的宽度为 100px,于是,父元素的剩余宽度就变成 600 – 3×100 = 300px。
box1 和box2 定义了 flex-grow属性,box3 未定义。故 box1 和 box2 把剩余空间分成 2 + 1 = 3 份,box1 占 2/3,box2 占 1/3。于是,box1、box2 按 3:1 来分配这 300px,box3 不分配。box1 分得 300×(2/3) = 200px,box2 分得 300×(1/3) = 100px。
最终的结果是,box1 和 box2 在预分配空间的基础上,又分得了剩余空间,而 box3 仅有原本的 100px 而已。运行结果如图 9‑19 所示:

可以看出,box1 的实际宽度为100 + 200 = 300px,box2的实际宽度为100 + 100 = 200px,box3 的实际宽度仍然是 100px。
flex-shrink属性
flex-shrink属性定义子元素的收缩因子,当容器空间不足时,浏览器把所有子元素的 flex-shrink属性值相加,再根据各自在总值中所占的份额进行收缩。语法为:
flex-shrink: <number>
flex-shrink属性的默认值为 1。不允许负值,0 表示不收缩。如,父元素 father 下有两个子元素 box1、box2。HTML代码如下:
<div class="father">
<div class="box1">1</div>
<div class="box2">2</div>
</div>
CSS代码如下:
.father {
width: 600px;
display: flex;
}
.box1 {
width: 400px;
flex-shrink: 3;
background: #7f3ffd;
}
.box2 {
width: 400px;
background: #ef39d5;
}
上述代码中,父元素的宽度是 600px,每个子元素的宽度是 400px,于是,父元素的宽度不足。为了能够容纳所有子元素,子元素需要收缩,待收缩的宽度为 2×400 – 600 = 200px。
box1 定义了 flex-shrink属性,box2 未定义,box2 的 flex-shrink属性使用默认值 1。box1, box2 把待收缩空间分成 3 + 1 = 4份,box1 占 3/4,box2 占 1/4。于是,box1 和 box2按 3:1 来分配这 200px,box1要收缩 200×(3/4) = 150px,box2 要收缩 200×(1/4) = 50px。
最终的结果是,box1 的实际宽度为 400 – 150 = 250px, box2 的实际宽度为400 – 50 = 350px。运行结果如图 9‑20 所示:

flex-basis属性
flex-basis属性用来定义为子元素预留的主轴尺寸。语法为:flex-basis: <length> | auto,默认值为 auto。
取值值为 auto 时,实际使用的值是主轴尺寸属性的值,即 width 或 height 属性的值。如果主轴尺寸属性的值也是 auto,则要根据其内容和 flex-grow属性来分配空间。
取值为长度值时,首先为该元素预留空间,预留后剩余的空间,再分配给所有子元素。这样一来,该元素除了预留空间外,还会分得容器的剩余空间。在父元素的空间有剩余时,该元素分配的空间 = flex-basis + flex-grow;在父元素空间不足时,该元素分配的空间 = flex-basis - flex-shrink。
如,父元素 father 下有两个子元素 box1、box2。HTML代码如下:
<div class="father">
<div class="box1">1</div>
<div class="box2">2</div>
</div>
CSS代码如下:
.father {
width: 400px;
display: flex;
}
.box1 {
flex-grow: 1;
flex-basis: 200px;
background: #7f3ffd;
}
.box2 {
flex-grow: 1;
background: #ef39d5;
}
上述代码中,父元素的宽度是 400px。box1 定义了 flex-basis属性,预留了 200px 的空间。而 box2 未定义 flex-basis属性,并未预留空间。这样一来,父元素剩余的空间就变成了 400 – 200 = 200px。
由于 box1, box2 的 flex-grow属性的值都是 1,故由 box1, box2 均分父元素的剩余空间,各分得 100px。最终结果是,box1 的实际宽度为 200 + 100 = 300px, box2 的实际宽度为 100px。运行结果如图 9‑21 所示:

flex属性
flex属性是 flex-grow、flex-shrink、flex-basis 这 3 个属性的复合属性,用来定义子元素如何分配父元素的空白空间。语法格式为:
flex: none | [ <"flex-grow"> <"flex-shrink">? || <"flex-basis"> ]
取值为关键字 none 时,相当于 flex-grow 的值为 0、flex-shrink 的值为 0、flex-basis的值为 auto。也就是说,flex: none 就相当于 flex: 0 0 auto。除此之外,flex属性还可以使用以下常用值:
1) flex: initial,这是 flex属性的初始值,它表示 flex-grow、flex-shrink、flex-basis 这 3 个属性均使用默认值,就相当于flex: 0 1 auto。
2) flex: auto,相当于 flex: 1 1 auto,表示子元素的实际尺寸为 width 或 height 属性的值,并子元素可以根据弹性容器的空间自由伸缩。
3) flex: <positive-number>,相当于 flex: <positive-number> 1 0%,表示为子元素预留的主轴尺寸为0,并根据设置的比率分配弹性容器的剩余空间。如果一个伸缩容器里的所有项目都使用此模式,则它们按各自指定的伸缩比率分配弹性容器的剩余空间。
align-self属性
align-self属性用来定义当容器在侧轴方向上有额外的空白空间时,该子元素如何分配多余的空间,或容器的空间不足时,如何分配溢出的空间。
align-self属性用来覆写容器上 align-items属性,除了 align-items属性的所有可选值外,align-self属性还可以设置为 auto,表示其计算值是弹性容器的 align-items属性值;如果弹性容器未定义 align-items属性,则为 stretch。