百分比高度在flex子项中失效,是因为父容器computed height为auto,导致100%×0px=0px;flex:1可行因其基于剩余空间分配而非继承像素高度,且需父容器display:flex并有确定高度。

它不是“不起作用”,而是浏览器按规范算出了 0px —— 因为父容器的 height 是 auto,100% × 0px = 0px,结果就是看不见。
为什么 Flex 容器本身不提供 height 参照
很多人以为加了 display: flex 就自动有了高度上下文,其实不然。Flex 容器默认仍是 height: auto,它只负责排列子项,不负责“撑高自己”。子项写 height: 100% 时,浏览器查它的直接父级(也就是这个 Flex 容器)的 computed height,发现是 auto,立刻放弃计算。
- 用开发者工具选中该 Flex 容器 → 切到「Computed」面板 → 看
height值是不是具体像素(如720px或100vh),如果是auto,链就断了 -
align-items: stretch不会生效,因为拉伸需要“可拉伸的空间”,而空间来源是父容器的高度,不是display: flex这个声明本身 - UI 框架(如 Ant Design)可能悄悄给容器加了
min-height: 0,这会进一步压制拉伸行为,需手动覆盖为min-height: auto
为什么 flex: 1 更可靠
flex: 1 不依赖父容器有没有像素高度,它靠的是主轴剩余空间分配逻辑。只要父容器是 display: flex 且自身有明确高度(比如 height: 100vh 或被上层 flex: 1 撑开),子项就能参与分配。
-
flex: 1等价于flex: 1 1 0,表示从0开始分剩余空间 - 别同时写
flex: 1和height: 100%:Chrome 会优先按 flex 规则走,Safari 14–15.6 可能直接忽略height - 若子项含文字或图片,
flex-basis: 0可能压扁内容,改用flex: 1 1 auto更稳妥
哪些地方最容易漏掉高度声明
最常卡住人的,不是没写 height,而是写了却没生效——因为你没打开开发者工具逐层看 computed height 到底是不是像素值。
-
html和body必须同时设height: 100%;只设body没用,html是它的父级 - 某些 CSS reset(如 Normalize.css)会重置
html的height,得在「Computed」里确认它确实是具体数值,而不是auto - 中间某层用了
position: absolute、float或display: inline,导致它不再是子元素的包含块 - UI 框架注入的
min-height: 0或align-self: flex-start阻断了默认拉伸
Safari 14–15.6 的特殊限制
这不是兼容性补丁能解决的问题,是 Safari 引擎级缺陷:哪怕父容器写了 height: 100vh,子元素的 height: 100% 依然被当成无效声明处理,最终渲染为 auto。
- 它只认显式
height声明,min-height、flex: 1推导出的高度都不行 - 嵌套 Flex 时更危险:外层
column、内层row,必须每层 Flex 容器都设height或flex: 1,Safari 不会自动穿透 - 解法不是堆
!important,而是删掉子项的height: 100%,改用默认align-items: stretch+ 确保父容器有height
真正容易被忽略的,是没打开开发者工具逐层点开看 computed height —— 多数人卡在“我明明写了 html, body { height: 100% } 还是不行”,其实断点常在第三层,比如某个 .main 用了 position: relative 却没设高。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











