先记住这个答案
align-content 和 align-items 都作用在交叉轴上,但层级不同。align-content 把多条 flex line 当作整体来分配空间,比如让所有行居中、等间距排列或拉伸填满。align-items 则是在每条 line 内部,决定子项是靠上、靠下、居中还是拉伸。两者同时生效时,先由 align-content 决定每行的位置和高度,再由 align-items 决定行内子项的对齐。
align-content管行与行之间align-items管行内子项- 必须搭配
flex-wrap: wrap - 单行时
align-content无效
什么时候有多条 flex line
默认 flex-wrap: nowrap 时,不管放多少子项都只有一条 flex line,所有子项挤在一行里,最多溢出。只有设了 flex-wrap: wrap,子项排不下时才会换到下一行,每行就是一条 flex line。
所以要让 align-content 起作用,两个条件缺一不可:一是容器设了 flex-wrap: wrap,二是子项确实换了行。光写 wrap 但子项总宽度没超过容器,还是只有一行,align-content 仍然不生效。
.container {
display: flex;
flex-wrap: wrap;
height: 400px;
align-content: space-between; /* 行间距平分 */
align-items: center; /* 每行内子项垂直居中 */
}
.item {
width: 45%; /* 一行放两个,第三个换行 */
height: 60px;
}这段代码的效果是:第一行贴顶、最后一行贴底、行间距平分(这是 align-content 干的),同时每行里的子项在行内垂直居中(这是 align-items 干的)。
align-content 会「压制」align-items
当 align-content 不是 stretch(默认值)时,它会重新计算每条 line 的高度。比如 align-content: flex-start 会让所有行紧挨着贴在顶部,每行的高度就等于最高子项的高度,没有多余空间。这时候 align-items: center 和 align-items: flex-start 看起来差不多,因为行内已经没有额外的交叉轴空间给子项移动了。
只有 align-content: stretch 时,行会被拉伸到平分容器交叉轴空间,行内才会有足够的空间让 align-items 的效果明显。
容易答错的地方
- 以为
align-content和align-items是互斥的 - 它们同时生效,不是二选一。
align-content决定行在容器里怎么放,align-items决定子项在行里怎么放。 - 只加了
flex-wrap: wrap以为就够了 wrap只是允许换行,但如果子项总宽度没超过容器,还是不会换行。align-content的效果取决于实际有没有产生多行,而不是有没有写wrap。
面试官还会怎么问?
align-content 在 Grid 布局里也是这样工作的吗?
大致相同,但 Grid 的 align-content 对单行也有效,不需要像 Flexbox 一样必须有多行。Grid 里它分配的是行轨道之间的空间。
align-content: stretch 和不写有什么区别?
stretch 就是默认值,不写等于写了 stretch。效果是多余的交叉轴空间平均分配给每条 line,让行高拉伸填满容器。
align-self 和 align-content 冲突时谁优先?
align-content 先确定每行的位置和高度,align-self 只能在这个已经确定的行高范围内调整单个子项的位置。所以 align-content 设定了行的空间上限,align-self 在这个范围内生效。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。