height: 100% 失效的根本原因是父元素高度为 auto,需确保 html 和 body 均设 height: 100% 并重置 margin/padding;中间任意父容器若 height 为 auto、脱离文档流(如 inline/table-cell/float/absolute)或 flex 设置冲突(如 min-height: 0、align-self 非 stretch),均会导致链路中断;推荐优先使用 flex: 1 替代 height: 100%,避免依赖高度链;100vh 虽见效快但易受视口变化影响,稳定性不如百分比链。

height: 100% 没生效,不是你漏写了分号或拼错了单词,而是浏览器根本算不出“100% 等于多少像素”——它只认直接父元素的 computed height,而这个值十有八九是 auto。
html 和 body 必须同时设 height: 100%
只写 body { height: 100%; } 是无效的。因为 body 的父元素是 html,而它的默认 height 就是 auto。没有源头高度,整条链就断了。
- 必须加这段基础重置:
html, body { margin: 0; padding: 0; height: 100%; } - 某些 CSS reset(如 Normalize.css)会悄悄把
html的height设为0或auto,得用开发者工具「Computed」面板确认它确实是具体数值,而不是auto - 漏掉
margin: 0; padding: 0;可能导致实际可用高度小于视口,尤其在旧版 Safari 中
中间任意一层父容器是 auto,子元素就全白搭
即使 html 和 body 都设对了,只要中间某层(比如 .wrapper、.main、.grid-container)的 computed height 是 auto,子元素的 height: 100% 就立刻退化为内容撑开高度。
- 用开发者工具逐级点击目标元素的每个父节点,在「Computed」面板里查
height值:出现auto的那一层就是断点 - 常见断链原因:
display: inline、display: table-cell、float: left、position: absolute—— 这些会让该元素脱离文档流,不再作为有效“包含块” -
min-height或max-height不提供百分比计算基准,只有height属性本身或vh单位才行
Flex 容器里别硬套 height: 100%,改用 flex: 1
Flex 子项默认靠 align-items: stretch 拉伸,但这个行为极易被破坏:UI 库常加 min-height: 0,或者你写了 align-self: flex-start,此时再叠 height: 100% 完全无效。
立即学习“前端免费学习笔记(深入)”;
- 更可靠的是:
flex: 1(即flex-grow: 1; flex-shrink: 1; flex-basis: 0),它不依赖父容器有没有显式height,而是从 0 开始吃掉剩余空间 - 前提:父容器必须是
display: flex或display: inline-flex;若父容器是flex-direction: column,且已有固定高头部/底部,中间区域加flex: 1就能自动填满 - 如果必须保留
height: 100%(比如内部要嵌套非 Flex 元素),需组合设置:min-height: 0; align-self: stretch;
别迷信 100vh,它绕过链路但代价明显
100vh 能立刻见效,但它绑定的是“当前视口”,不是“父容器”。真实项目里一碰滚动、缩放、固定定位就容易翻车。
- iOS Safari 地址栏收起/展开时,
vh值会重算,页面视觉跳动 - 若目标元素在
overflow: auto的容器内,100vh会让它溢出该容器,脱离滚动上下文 - 页面有
position: fixed头部时,100vh仍按完整屏幕计算,常导致底部留白或遮挡内容 - 用户缩放页面(
Ctrl +/Cmd +),vh不随布局缩放,而百分比链下的height: 100%更稳定
真正卡住人的,从来不是怎么写,而是没打开开发者工具逐层点开看「Computed → height」——绝大多数人的问题,藏在第三层或第四层父容器里,比如某个 .container 被 position: relative 和 top: 10px 干扰了包含块判定,或者框架悄悄加了 min-height: 0。


















