先记住这个答案
align-content 是用来分配多条 flex line 之间的交叉轴空间的。默认 flex-wrap: nowrap 时,容器里只有一条 flex line,没有「行间距」可分配,所以 align-content 设成 center、space-between 或任何值都不起作用。想控制单行子项的交叉轴对齐,应该用 align-items。
align-content管行间距- 单行没有行间距可分配所以无效
- 单行交叉轴对齐用
align-items - 新规范已允许单行生效
一条 flex line 和多条 flex line 的区别
flex 容器默认不换行,所有子项挤在同一行(同一条 flex line)里。这时候 align-content 没有「行」可以操作。只有加了 flex-wrap: wrap 之后,子项排不下才会换到下一行,产生多条 flex line。这时 align-content 才有两条以上的行去分配空间。
/* 单行:align-content 无效 */
.single {
display: flex;
flex-wrap: nowrap; /* 默认值,可省略 */
align-content: center; /* 不起作用 */
align-items: center; /* 这才管用 */
height: 300px;
}
/* 多行:align-content 生效 */
.multi {
display: flex;
flex-wrap: wrap;
align-content: center; /* 把所有行整体居中 */
height: 300px;
}一个简单的判断方法:如果你的 flex 容器不会换行,就不用考虑 align-content,直接用 align-items。
新规范的变化
从 2024 年开始,CSS 规范做了一项调整:align-content 在单行 flex 容器、甚至普通的 display: block 元素上也能生效了。Chrome 123 和 Safari 17.4 已经支持这个新行为。这意味着以前要写 display: flex; align-items: center; justify-content: center 才能实现的垂直居中,现在一句 align-content: center 就够了。
不过面试时考的通常还是经典行为,回答的时候先讲「单行不生效」的原因,再补一句「新规范已经放开了」,面试官会觉得你跟进得比较紧。
容易答错的地方
- 把
align-content和align-items搞混 - 最常见的错误就是在单行容器上用
align-content居中,发现不生效又怀疑自己写错了。记住:align-items管单行里每个子项怎么对齐,align-content管多行之间怎么分布。 - 以为加了
flex-wrap: wrap就一定有多行 flex-wrap: wrap只是允许换行,如果子项总宽度没超过容器,它们还是在一行里。这时align-content一样没效果。要看到效果,容器宽度必须不够放下所有子项,让它们实际换到下一行。
面试官还会怎么问?
Grid 布局里 align-content 在单行时有效吗?
有效。Grid 和 Flexbox 不同,Grid 的 align-content 管的是行轨道之间的空间,哪怕只有一行也能生效。这是两种布局模型的一个重要区别。
怎么用最少的 CSS 让一个元素垂直水平居中?
如果只需要支持新浏览器,给父元素加 align-content: center 加 justify-content: center 就行,甚至不需要 display: flex。如果要兼容旧浏览器,经典写法是 display: flex; align-items: center; justify-content: center。
align-content: stretch 在多行时是什么效果?
stretch 是 align-content 的默认值。它会把多条 flex line 拉伸到填满容器的交叉轴空间,每行平分多出来的高度。如果子项自身没有设高度,它们会跟着行的高度一起拉伸。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。