先记住这个答案
多行 flex 容器没设显式高度(height: auto)时,容器的高度就是所有行加起来的高度。每行的高度等于行内最高子项的高度。行与行之间紧挨着排列,容器刚好包住所有行,没有多余的交叉轴空间。这时候 align-content 设成 center、space-between 还是 stretch 看起来都一样,因为没有空间可以分配。
- 无高度时容器被内容撑开
- 行高 = 行内最高子项的高度
- 行与行紧挨着排列
align-content看不出效果
行高是怎么确定的
浏览器处理多行 flex 容器时,先把子项分到各行(根据 flex-wrap: wrap 和容器宽度),然后计算每行的高度。每行的高度取最高的那个子项:如果一行有三个子项,高度分别是 40px、80px、60px,这一行的高度就是 80px。
如果 align-items: stretch(默认值),其余子项会被拉伸到行高(80px)。如果是 flex-start,子项保持自己的高度,行的高度还是 80px,只是子项不一定填满。
.container {
display: flex;
flex-wrap: wrap;
width: 300px;
/* 没设 height,容器被内容撑开 */
}
.item-tall { height: 80px; width: 150px; }
.item-short { height: 40px; width: 150px; }
/* 每行放 2 个 item */
/* 第一行:80px 和 40px,行高 80px */
/* 容器高度 = 第一行 80px + 第二行高度 + ... */容器的总高度就是所有行高度加起来(加上 row-gap 如果有的话)。
加了显式高度之后会怎样
如果给容器设了一个固定高度,比如 height: 400px,但内容只占了 240px,就有 160px 的多余空间。这时 align-content 才有事可做。
align-content: flex-start 把行都贴在顶部,160px 空白在底部。align-content: center 把行整体居中,上下各 80px 空白。align-content: stretch 把多余空间平均分给每行,让行变高。
所以 align-content 的效果完全取决于有没有多余的交叉轴空间。没有显式高度就没有多余空间,自然看不到效果。
容易答错的地方
- 以为行高是容器高度平均分
- 只有
align-content: stretch加上容器有显式高度时,多余空间才会被平分给各行。如果容器没有显式高度或者align-content不是stretch,每行的高度就是行内最高子项的高度。 - 以为
align-content: center在没有高度的容器里能居中 - 没有高度时容器刚好包住内容,没有多余空间,
center和flex-start看起来完全一样。要让center生效,容器必须比内容高。
面试官还会怎么问?
row-gap 会影响容器高度吗?
会。没有显式高度时,容器高度等于所有行高度加上所有 row-gap 的总和。row-gap: 10px 在三行之间产生两个 10px 间距,容器总高度多出 20px。
min-height 能不能代替 height 让 align-content 生效?
可以。min-height 设了一个最小值,如果内容没有填满这个最小高度,多余的空间可以被 align-content 分配。和 height 的区别是内容超出时容器还能继续撑开。
Grid 布局里行高也是这样算的吗?
Grid 的行高由 grid-template-rows 定义,可以是固定值、百分比或 fr 单位。如果用 auto,行高等于行内最高的子项,和 flex 类似。但 Grid 提供了更精确的控制。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。