根本原因是父级计算高度为auto导致子元素100%高度失效,需确保html、body及所有中间父级显式设height:100%并检查包含块有效性。

根本原因不是写错了,而是浏览器压根没拿到可计算的高度值——父级 computed height 是 auto,100% × 0px = 0px,子元素自然塌缩成一条线甚至不可见。
检查 html 和 body 是否显式设了 height: 100%
这是最常被跳过的源头。浏览器里 html 和 body 默认不占满视口高度,它们只是“包裹内容”的容器。如果其中任意一个的 computed height 是 auto,整条链就断了。
- 必须同时写:
html, body { margin: 0; padding: 0; height: 100%; } - 仅写
body { height: 100%; }不够,因为body的100%是相对于html的,而html没高,body的100%还是0px - 某些 CSS reset(如 Normalize.css)会悄悄重置
html或body的height,得用开发者工具的「Computed」面板确认它们的height确实是像素值,不是auto
逐层检查父级 computed height 是否为 auto
即使 html 和 body 都设了 height: 100%,中间某层父容器用了 display: inline、position: absolute 或 float,也会让包含块失效,导致 height: 100% 回退到视口或直接退化为 auto。
-
display: inline、display: table-cell、display: float的父元素无法作为有效包含块,子元素的百分比高度会跳过它往上找 -
position: absolute元素的包含块是最近的position: relative/absolute/fixed祖先,不是视觉父级;若没找到,就按视口算 - 用开发者工具逐层点开目标元素及其所有父级,在「Computed」面板里查
height:只要出现auto,就说明这一层断了
Flex 容器里别硬套 height: 100%
Flex 子项一旦声明 height: 100%,浏览器就认为你手动接管高度控制,会忽略默认的 align-items: stretch 行为——即使父容器有明确高度,子项也不会自动拉伸。
- 删掉所有子元素上的
height: 100%、min-height: 100%、max-height: 100% - 想填满剩余空间?直接用
flex: 1(等价于flex-grow: 1; flex-shrink: 1; flex-basis: 0),它不依赖父容器有没有显式height,只认剩余空间 - 嵌套 Flex 时,子 Flex 容器需加
min-height: 0,否则默认min-height: auto会阻止内部flex: 1生效 - 别同时写
align-self: stretch和height: 100%——前者是默认行为,后者冗余且在 Safari 14–15.6 中可能触发兼容问题
100vh 看似简单,但实际容易翻车
100vh 绕过了百分比链路,直接取视口高度,所以写上去立刻“见效”。但它绑定的是视口,不是父容器,在真实项目里常出问题:
- 放在
overflow: auto的滚动区域里,100vh会让子元素溢出该区域,而不是填满它 - iOS Safari 地址栏收/放时,
vh值重算,页面突然跳动 - 有
position: fixed头部时,100vh仍按全屏算,底部常留白或被遮挡 - 用户缩放页面(
Cmd +),vh不随布局缩放,而百分比链路下的height: 100%更稳定 - 真正需要“嵌套填满”(比如 Grid 区域内再套 Flex),
100vh会破坏层级语义,必须回归显式高度链
最容易被忽略的是:即使所有样式都写了,box-sizing: content-box(默认)下,padding 和 border 会吃掉可用高度;还有 UI 框架悄悄加的 min-height: 0,会卡住 Flex 拉伸——这些细节不查「Computed」面板,光看代码根本发现不了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











