先记住这个答案
交叉轴永远和主轴垂直。flex-direction: row 时主轴水平,交叉轴就是垂直方向。flex-direction: column 时主轴垂直,交叉轴就是水平方向。所有 align-* 属性(align-items、align-self、align-content)都沿交叉轴方向工作,具体是上下还是左右取决于 flex-direction。
- 交叉轴永远垂直于主轴
row下交叉轴是垂直方向column下交叉轴是水平方向align-*属性跟着交叉轴走
row 和 column 下的交叉轴对比
默认 flex-direction: row 时,大多数人对交叉轴的理解没有问题:align-items: center 让子项垂直居中,align-items: flex-start 让子项靠顶。这时交叉轴是垂直的。
改成 column 后,所有方向翻转。align-items: center 变成水平居中,align-items: flex-start 让子项靠左。因为交叉轴变成了水平方向。
align-items 的效果CSS/* row:交叉轴垂直,align-items 管上下 */
.row {
display: flex;
flex-direction: row;
align-items: center; /* 子项垂直居中 */
}
/* column:交叉轴水平,align-items 管左右 */
.col {
display: flex;
flex-direction: column;
align-items: center; /* 子项水平居中 */
}同一个 center,在 row 下居中是上下方向的,在 column 下是左右方向的。这就是为什么说 align-items 管的是交叉轴,而不是「垂直方向」。
reverse 不影响交叉轴方向
row-reverse 让子项从右到左排,但交叉轴仍然是垂直的。column-reverse 让子项从下到上排,交叉轴仍然是水平的。
reverse 只改变子项在主轴上的排列顺序,同时交换 flex-start 和 flex-end 的含义,但不影响交叉轴。所以 row-reverse 下 align-items: flex-start 还是让子项靠顶,只是子项的水平顺序反了。
容易答错的地方
- 把交叉轴固定理解成垂直方向
- 这是最常见的误解。交叉轴不是固定的,它的方向取决于
flex-direction。只有row(默认)时交叉轴是垂直的。一旦改成column,交叉轴就变成水平的了。 - 以为
reverse也会翻转交叉轴 reverse只翻转主轴方向。row-reverse下交叉轴还是垂直的,column-reverse下交叉轴还是水平的。只有flex-direction从row变成column(或反过来)才会翻转交叉轴。
面试官还会怎么问?
column 下 align-content 管的是什么方向?
水平方向。column 下交叉轴是水平的,align-content 分配的是多列之间的水平空间(前提是 flex-wrap: wrap 产生了多列)。
flex-wrap: wrap-reverse 会改变交叉轴方向吗?
wrap-reverse 不改变交叉轴的方向,但改变了换行的方向。row 加 wrap 时新行出现在下方,wrap-reverse 时新行出现在上方。align-items: flex-start 在 wrap-reverse 下是靠底而不是靠顶。
怎么快速判断某个 align-* 属性在当前方向下管的是哪个方向?
先看 flex-direction 确定主轴方向,然后交叉轴就是垂直于它的那个方向。align-* 永远沿交叉轴工作。row 下 align-* 管上下,column 下 align-* 管左右。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。