先记住这个答案
flex-direction: row 是默认值,子项从左到右水平排列。改成 column 后子项从上到下垂直排列。最重要的影响不只是排列方向变了,而是所有和轴相关的属性都跟着翻转了:justify-content 从管水平变成管垂直,align-items 从管垂直变成管水平。flex-basis 从控制宽度变成控制高度。
row水平排列,column垂直排列- 切换方向后对齐属性方向也翻转
column下子项宽度默认填满column下换行变成换列
对齐属性的方向跟着翻转
row 下 justify-content: center 让子项水平居中,align-items: center 让子项垂直居中。改成 column 后完全反过来:justify-content: center 变成垂直居中,align-items: center 变成水平居中。
/* row:水平排列 */
.row {
display: flex;
flex-direction: row;
justify-content: space-between; /* 水平等间距 */
align-items: center; /* 垂直居中 */
}
/* column:垂直排列 */
.col {
display: flex;
flex-direction: column;
justify-content: space-between; /* 垂直等间距 */
align-items: center; /* 水平居中 */
}如果你把 align-items 理解成「管垂直」就会搞混。要记住它管的是交叉轴,方向随 flex-direction 变化。
column 下子项的默认尺寸
row 下子项的宽度由内容或 flex-basis 决定,高度默认被 align-items: stretch 拉伸到行高。
column 下反过来:子项的高度由内容决定,宽度默认被 stretch 拉满容器宽度。这就是为什么 column 下的子项通常是全宽的——如果不想全宽,要给子项设 width 或者用 align-items: flex-start。
flex-basis 在 column 下控制的是高度
flex-basis 始终控制主轴方向上的初始尺寸。row 下控制宽度,column 下控制高度。同理,flex-grow 和 flex-shrink 在 column 下也是在垂直方向上伸缩。
这意味着 flex: 1 在 column 下让子项的高度按比例填满容器,不是宽度。容器要有固定高度,flex-grow 才有空间可分。
容易答错的地方
- 以为只是排列方向变了
- 方向变了只是表象,真正的变化是整个轴系统翻转了。所有和轴相关的属性(
justify-content、align-items、flex-basis、flex-wrap的换行方向)都要重新理解。 column下忘了给容器设高度column下flex-grow需要容器有固定高度才能分配空间。flex-wrap: wrap也需要容器有固定高度才能触发换列。如果容器高度是auto,它会自动撑高容纳所有子项。
面试官还会怎么问?
row-reverse 和 column-reverse 会影响 Tab 键的顺序吗?
不会。reverse 只改变视觉顺序,不改变 DOM 顺序和键盘导航顺序。用户按 Tab 键还是按 DOM 里的顺序走。这对无障碍访问很重要,视觉顺序和焦点顺序不一致会让用户困惑。
什么时候用 column,什么时候用普通的块级布局?
如果子项需要 flex-grow、align-items 等弹性能力(比如等高卡片、垂直居中、按比例分配高度),用 column。如果只是简单的上下排列,普通块级布局就够了,不需要 flex。
column 下怎么实现等高分栏?
给容器设固定高度和 flex-wrap: wrap,子项排不下就换列。但这不是真正的等高分栏——列高是固定的(等于容器高度),不是由内容最多的列决定的。如果要内容驱动的等高分栏,用 Grid 的 grid-template-columns 更合适。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。