先记住这个答案
align-items: stretch 是 flex 容器的默认行为,它让子项在交叉轴方向拉伸,填满整条 flex line 的高度。这就是为什么 flex 子项默认都「等高」。但有一个前提:子项自身不能有显式的交叉轴尺寸。在 flex-direction: row 下,只要子项设了 height,stretch 就失效了。
stretch是align-items的默认值- 子项没有显式交叉轴尺寸才拉伸
- 设了
height后stretch不再生效 - 最小或最大高度会限制拉伸
为什么 flex 子项默认会「等高」
写一个 flex 容器,里面放几个内容量不同的子项,你会发现它们全变成一样高了。这不是什么 CSS 魔法,而是 align-items: stretch 在起作用。
每条 flex line 的高度由行内最高的子项决定。stretch 让其余子项拉伸到这个高度,所以看起来所有子项等高。
stretch 和 flex-start 的差异CSS.container {
display: flex;
/* align-items: stretch 是默认值,可以省略 */
}
.item-a { /* 内容高 40px */ }
.item-b { /* 内容高 100px */ }
.item-c { /* 内容高 60px */ }
/* stretch 下:三个子项都变成 100px 高 */
.container-start {
display: flex;
align-items: flex-start;
}
/* flex-start 下:各自保持内容高度 40/100/60px */从 stretch 切换到 flex-start,等高效果就消失了,每个子项回到自己的内容高度。
什么时候 stretch 不生效
stretch 生效的前提是子项在交叉轴方向上没有明确的尺寸。在 row 方向下,只要子项写了 height,stretch 就不拉伸了,子项用自己设的高度。
min-height 和 max-height 也会限制拉伸范围。子项最多拉到 max-height,最少保持 min-height。
另外 align-self 的优先级高于 align-items。如果某个子项设了 align-self: flex-start,即使容器是 stretch,这个子项也不会被拉伸。
容易答错的地方
- 以为
stretch会拉伸主轴方向 stretch只作用在交叉轴上。row模式下只拉高度,不拉宽度。想让子项在主轴方向填满空间,用flex-grow: 1。- 给子项设了
height: auto以为能阻止拉伸 height: auto不算显式高度,stretch仍然生效。要阻止拉伸,需要设一个具体的值比如height: 100px,或者用align-self: flex-start。
面试官还会怎么问?
align-items: stretch 和 height: 100% 有什么区别?
stretch 是 flex 布局的行为,子项自动拉伸到行高,不需要知道父元素的高度。height: 100% 是百分比计算,如果父元素没有明确高度,百分比可能计算为 auto。在 flex 容器里两者视觉效果类似,但 stretch 更省心。
column 方向下 stretch 拉伸的是什么?
拉伸宽度。因为 column 下交叉轴是水平方向,stretch 让子项宽度填满容器。同样,子项设了 width 就不再拉伸。
怎么让等高卡片里的内容也撑满?
flex 的 stretch 只拉伸子项本身的高度,子项里面的内容不会自动填满。解决办法是让子项也变成 flex 容器(嵌套 flex),然后让内容区域 flex-grow: 1 来撑满剩余空间。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。