父元素 computed height 为 auto 时 height: 100% 必然失效,因浏览器按 100% × 0px = 0px 计算导致子元素塌缩;需逐层检查 html、body 及所有中间父级的 computed height 是否均为具体像素值,任一层为 auto 则整条百分比链中断。

父元素 computed height 是 auto 就必然失效
浏览器计算 height: 100% 时,只认直接父元素的 **computed height** 值。如果这个值是 auto(块级元素默认值),那 100% × auto = 0px —— 子元素不是“没生效”,而是真真切切被算成了 0 高度,视觉上塌缩或消失。
常见断点位置:
-
html或body没设height: 100%(二者必须同时写,缺一不可) - 中间某层用了
display: inline、display: table-cell或float,导致它无法作为有效包含块 - 父元素是
position: absolute且没配top/bottom,脱离文档流后高度坍缩 - Flex 容器自身
height仍是auto,子项的百分比无基准可依
验证方法:打开开发者工具 → 选中目标元素 → “Computed” 面板里直接看 height 行。显示 auto 就说明链断了;显示具体像素(如 428px)才表示这一层有高。
Flex 容器里硬写 height: 100% 反而禁用拉伸
Flex 子项一旦声明 height: 100%,浏览器就认为你手动接管高度控制,会主动忽略默认的 align-items: stretch 行为——哪怕父容器有明确高度,子项也不会自动撑满。
立即学习“前端免费学习笔记(深入)”;
更可靠的做法是删掉所有 height: 100%、min-height: 100%,改用:
-
flex: 1(等价于flex-grow: 1; flex-shrink: 1; flex-basis: 0),从 0 开始拉伸吃剩余空间 - 若父容器是
flex-direction: column,且已有固定高头部/底部,中间区域加flex: 1即可自动填满 - 注意某些 UI 库会给子项加
min-height: 0,这会卡住拉伸,需显式覆盖为min-height: auto
100vh 看似简单,实际在嵌套和滚动场景下容易溢出
100vh 绕过了百分比链路,直接取视口高度,所以写上去立刻“见效”。但它绑定的是视口,不是父容器,在真实项目里常翻车:
- 放在
overflow: auto的滚动区域里,100vh会让子元素撑出该容器,脱离滚动上下文 - iOS Safari 地址栏收起/展开时,
vh值重算,页面突然跳动 - 有
position: fixed头部时,100vh仍按全屏算,底部常留白或被遮挡 - 用户缩放页面(
Cmd +),vh不随布局缩放,而百分比链下的height: 100%更稳定
真正需要“占满父容器”的场合(比如 Grid 区域内再套 Flex),100vh 会破坏层级语义,必须回归显式高度链。
box-sizing 和定位干扰常被忽略
即使高度链通了,padding、border、margin 或 position 仍可能让视觉结果错位:
-
box-sizing: content-box(默认)下,height: 100%只控制内容区高度,padding和border会额外增加总高 -
position: absolute元素的包含块可能跳过视觉父级,回退到html或视口,此时要查的是那个“真正包含块”的高度 - 别同时写
align-self: stretch和height: 100%—— 前者是默认行为,后者冗余且在 Safari 14–15.6 中可能触发兼容问题
最该盯住的,永远是开发者工具里 “Computed” 面板中的 height 值。只要其中一层是 auto,整条链就断了——这不是 CSS 写得不够多,而是根本没确认过源头有没有高。


















