先记住这个答案
flex-grow: 0 是默认值。它的意思是:容器里有剩余空间时,这个子项不去要,不增长。子项的宽度就停在 flex-basis 决定的大小上。这就是为什么 flex 子项默认不会自动填满容器——你需要显式设 flex-grow: 1 或者用 flex: 1 缩写才能让子项增长。
flex-grow: 0是默认值- 子项不会增长来填满空间
- 宽度由
flex-basis决定 flex: 1让子项填满剩余空间
为什么 flex 子项默认不填满容器
很多刚学 flex 的人觉得奇怪:用了 display: flex 之后,子项怎么没有自动撑满?这是因为 flex-grow 默认是 0,子项不参与剩余空间的分配。容器右边(或下方)会留一片空白。
flex-growCSS.container {
display: flex;
width: 600px;
}
/* 默认行为:flex-grow: 0 */
.item { width: 100px; }
/* 三个 item 占 300px,右边空 300px */
/* 加了 flex-grow: 1 */
.item-grow { flex-grow: 1; width: 100px; }
/* 三个 item 平分 300px 剩余空间,各变成 200px */flex-grow: 0 时容器有 300px 空白,设成 1 后空白被三个子项平分。
flex-grow: 0 但 flex-shrink 默认是 1
虽然 flex-grow: 0 不会增长,但 flex-shrink 默认是 1。这意味着空间不够时,子项会被压缩。这个行为有时候让人困惑:明明没让子项增长,怎么宽度变了?是因为被缩小了,不是增长了。
如果不想被压缩,可以设 flex-shrink: 0 或者用 flex: 0 0 auto,子项就完全保持固定尺寸。
flex: none 和 flex: auto 的区别
flex: none 展开为 flex: 0 0 auto——不增长、不缩小、基础尺寸按内容来。子项是完全刚性的。
flex: auto 展开为 flex: 1 1 auto——可以增长也可以缩小,基础尺寸按内容来。子项是完全弹性的。
flex: 1 展开为 flex: 1 1 0%——可以增长也可以缩小,基础尺寸为 0,所有空间按比例分。子项会平分空间。
这三个缩写覆盖了最常见的场景,比手写三个属性更常用。
容易答错的地方
- 以为
display: flex后子项就自动等分 display: flex只是开启了弹性布局,flex-grow默认是 0,子项不会自动填满。要等分需要每个子项都设flex: 1。- 以为
flex-grow: 0等于flex: 0 flex: 0展开为flex: 0 1 0%,flex-basis是0%,子项基础尺寸为 0。而flex-grow: 0只设了 grow,flex-basis还是默认的auto。两者基础尺寸不同。
面试官还会怎么问?
只有一个子项设了 flex-grow: 1,其他都是 0,会怎样?
那个子项独占所有剩余空间,其他子项保持 flex-basis 尺寸不变。这是 flex 布局里常见的模式:侧边栏固定宽度,主内容区 flex-grow: 1 自适应。
flex-grow 设成很大的数字(比如 999)有什么特别的?
没有特别的。flex-grow 是按比例分配的,999 相对于其他子项的 grow 值来说只是比例更大。如果只有一个子项有 grow 值,不管是 1 还是 999 效果一样——它独占所有剩余空间。
子项设了 min-width 会影响 flex-grow: 0 的行为吗?
flex-grow: 0 时子项宽度就是 flex-basis。如果 flex-basis 算出来比 min-width 小,子项宽度会被提升到 min-width。min-width 始终是硬限制,不管 grow 是多少。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。