先记住这个答案
flex-basis 的百分比相对于 flex 容器的主轴尺寸(即 content box 的宽度或高度,由 flex-direction 决定)。如果容器主轴尺寸不确定(如未显式设置且依赖内容),百分比无法计算,此时使用 content 值,即基于内容自动尺寸。例如在 column 方向且容器无固定高度时,flex-basis: 0% 与 0 不同:0% 回退为 content,0 仍是 0。
- 百分比相对主轴内部尺寸
- 主轴不定时回退为content
- 0与0%在column无高时不同
百分比的计算基准与回退规则
当 flex-basis 设为百分比时,该值首先相对 flex 容器的内部主轴尺寸(即 content box 的对应主轴长度)计算。例如在默认 row 方向下,此百分比基于容器 content 宽度;若设置 flex-direction: column,则基于容器 content 高度。这个基准不包含 padding、border 和 margin,但受 box-sizing 影响。
若 flex 容器的主轴尺寸无法由显式尺寸或包含块推导出来,则百分比成为不确定值。此时规范规定使用 flex-basis: content 的解析结果,即取该 flex 项的内容固有尺寸。注意这种回退只发生在百分比可能为任意值时,并不影响其他已确定尺寸的 flex 项。
column 无固定高度时 0% 与 0 的差异
考虑一个纵向 flex 容器,flex-direction: column,容器本身没有显式高度,其高度由内容决定。子项包含一个内容高度为 300px 的 div,且子项自身有最小高度 200px。当子项的 flex-basis 设为 0% 时,根据回退规则,百分比无法解析,因此使用 content 尺寸,即内容高度 300px,最终子项高度至少为 300px(或根据 grow/shrink 调整)。
若将 flex-basis 设为 0(绝对长度),则初始主轴尺寸确定为 0,之后 flex-grow 或 min-height 会起作用。在该场景中,由于没有设置 flex-grow,且容器高度不定,子项高度由 min-height: 200px 决定为 200px,内容高度 300px 会溢出子项(若未设置 overflow,内容可能溢出容器)。
<div style="display:inline-flex; flex-direction:column; border:1px dashed;">
<div style="flex-basis:0; min-height:200px; background:lightblue;">
<div style="height:300px;">内容</div>
</div>
</div>
<div style="display:inline-flex; flex-direction:column; border:1px dashed;">
<div style="flex-basis:0%; min-height:200px; background:wheat;">
<div style="height:300px;">内容</div>
</div>
</div>在浏览器中查看,第一个容器采用 flex-basis:0,子项因 min-height:200px 而高度为200px,内部内容溢出;第二个采用 flex-basis:0%,回退为 content 后子项高度为300px(内容尺寸),两个容器表现不同。
适用边界:何时百分比不会回退
百分比回退仅在 flex 容器主轴尺寸 indefinite 时发生。若容器具有确定的 width(在 row 方向)或 height(在 column 方向),例如显式设置或通过包含块继承,则百分比正常解析。此时 flex-basis: 50% 会让项目初始尺寸为容器的一半(但随后会被 flex-grow/shrink 调整)。
若同时设置了 width 和 flex-basis 百分比,则 flex-basis 优先决定初始主轴尺寸。当容器尺寸是确定的,但 flex 项本身设置了显式 width,flex-basis 百分比仍然相对于容器解析,忽略子项的 width。这种优先关系易被误解为百分比相对于自身宽度。
容易答错的地方
- percent 总是相对父元素宽度
- 错误认为 flex-basis 百分比只相对父容器宽度。实际上它相对主轴尺寸,column 方向时相对高度。且当父容器高度不定时,百分比会回退为 content,与固定百分比含义完全不同。
- 0 与 0% 在 column 无高时等价
- 在实际渲染中,0 是绝对长度,0% 在主轴不定时成为 content。此差异造成布局结果不同,需要区分使用场景。
面试官还会怎么问?
如果容器高度是 400px,flex-basis: 50% 在 column 方向会怎样?
容器高度确定,则 50% 解析为 200px。这是初始主轴尺寸,之后可被 flex-shrink 缩小或 flex-grow 扩大。
百分比受 box-sizing 影响吗?
flex-basis 的百分比相对 flex 容器的 content box。若容器 box-sizing: border-box,其 content 宽度等于外宽度减去 padding 和 border,因此间接受影响。
在 row 方向但容器宽度 auto(依赖内容)时,百分比如何?
容器宽度不定,则百分比无法解析,同样回退为 content。但通常容器宽度由 flex 项撑开,此时设置百分比没有意义。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。