先记住这个答案
flex-direction: column 搭配 flex-wrap: wrap 时,子项从上到下排列,排不下就换到下一列。这时交叉轴变成了水平方向。align-content: stretch(默认值)会把容器的水平空间平均分给每一列。如果容器 400px 宽、产生了两列,每列就是 200px。没有设显式宽度的子项会跟着列宽拉伸,效果就是各列等宽。
column下交叉轴是水平方向stretch让各列等分容器宽度- 容器要有高度才能触发换列
- 子项宽度跟着列宽拉伸
什么条件下才会产生多列
column 方向下,子项按垂直方向排列。只有容器设了固定高度,子项总高度超过容器高度时才会换列。如果容器没有固定高度或者高度设成 auto,容器会自动撑高来容纳所有子项,永远不会换列。
所以要让 align-content: stretch 在 column 下生效,两个前提缺一不可:容器有固定高度,并且子项实际产生了换列。
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 300px; /* 固定高度,让子项换列 */
width: 600px;
/* align-content: stretch 是默认值 */
}
.item {
height: 100px;
/* 没设 width,会被 stretch 拉伸到列宽 300px */
}
/* 3 个 item 高 300px,第 4 个换到第二列 */
/* 两列各分 300px 宽 */如果有四个子项,前三个填满第一列(3 x 100 = 300),第四个换到第二列。两列各分到容器一半的宽度,都是 300px。
改成其他 align-content 值会怎样
align-content: flex-start 会让所有列贴在容器左边,列宽由最宽的子项决定,不等分。align-content: center 会让所有列居中排列。align-content: space-between 让第一列贴左、最后一列贴右,中间等分间距。
只有 stretch 会让列宽等分并拉伸子项。其他值下,列宽取决于各列中最宽子项的宽度。
容易答错的地方
- 以为
align-content在column下管垂直方向 align-content始终管交叉轴。column下交叉轴是水平方向,所以align-content分配的是水平空间,不是垂直空间。- 忘了容器需要固定高度
- 没有固定高度,子项就不会换列,只有一列时
align-content没有多列可分配。stretch让唯一的一列占满整个宽度,但这不是「等分」的效果。
面试官还会怎么问?
column 方向下子项的宽度由什么决定?
如果 align-content: stretch(默认),列宽等分容器宽度,没有显式 width 的子项跟着列宽拉伸。如果子项设了 width,以设定值为准。如果 align-content 是其他值,列宽由列中最宽的子项决定。
怎么让各列宽度不等分,而是按内容自适应?
把 align-content 改成 flex-start 或 flex-end。这样每列的宽度由列中最宽的子项决定,不会被拉伸到等分。
用 Grid 实现等宽多列是不是更简单?
通常是的。grid-template-columns: repeat(2, 1fr) 直接定义两列等宽,不需要靠子项高度溢出来触发换列。Grid 对多列布局的控制力比 flex 的 column 加 wrap 更强。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。