height: 100% 失效的根本原因是父链中任一元素 computed height 为 auto,导致百分比计算中断;必须确保 html、body 及所有中间父元素显式设置高度(如 height: 100% 或 min-height: 100vh),或改用 flex: 1、top/bottom: 0 等更可靠的替代方案。

因为 height: 100% 不是“自动撑满”,而是“取父容器计算高度的 100%”;只要链上任意一层(html、body 或中间某层)的 computed height 是 auto,整条链就断了,最终结果就是塌成 0。
为什么 html 和 body 必须同时设 height: 100%
浏览器按规范从根向下计算百分比高度:html 是 body 的父元素,body 是你第一个 wrapper 的父元素。如果只写 body { height: 100% },而 html 仍是默认的 height: auto,那 body 的 100% 就等于 0 —— 它没地方可取。
-
html, body { height: 100%; margin: 0; padding: 0; }是最小必要配置 - 用 CSS reset 或 Bootstrap 自带的
reboot.css时,检查是否意外重置了html高度 - 在移动端,
height: 100%还可能被地址栏收起/展开干扰,此时min-height: 100vh更稳(但注意 iOS Safari 的 vh 跳动问题)
Bootstrap 的 .d-flex 容器自身不能靠 height: 100% 撑高
Bootstrap 的 .d-flex、.flex-column 等类只设置 display: flex,不提供任何高度约束。它不会继承或拉伸 —— 它只等父容器给一个“可用高度”,而父容器又在等它撑开,形成循环依赖。
- 错误写法:
.modal-body { height: 100% }→ 因为.modal-content默认是height: auto,100% 就是 0 - 正确解法:给
.modal-body的**直接父元素**(即.modal-content)加min-height: 500px或min-height: 80vh - 同理:
.card > .d-flex→ 给.card加min-height;.container > .d-flex→ 给.container加
Flex 子项用 flex: 1 比 height: 100% 更可靠
当父容器已是 flex 布局(比如 .d-flex.flex-column),子项要占满剩余空间,优先用 .flex-fill(即 flex: 1 1 auto)或手动写 flex: 1,而不是给它设 height: 100%。
立即学习“前端免费学习笔记(深入)”;
-
flex: 1是 flex 布局原生分配逻辑,不依赖父容器的 height 基准 -
height: 100%在 flex 子项中仍会退化为 auto,尤其当父容器高度未显式定义时 - 若子项内还有嵌套 flex 或 grid,且需进一步撑高,记得给中间层加
min-height: 0(防止 flex 最小尺寸限制干扰)
移动端和绝对定位元素的 height: 100% 特别容易失效
绝对定位元素的 height: 100% 不看 DOM 父子关系,只找最近的「非 static 定位祖先」作为包含块。如果那个祖先自己高度是 auto,结果还是 0。
- 常见陷阱:
.popup { position: relative; }+.popup > .content { position: absolute; height: 100%; }→ 若.popup高度由内容撑开,.content实际高 0px - 修复方式:给
.popup显式设min-height: 100vh,或改用top: 0; bottom: 0;绕过高度继承 - 横竖屏切换、键盘弹出时,
vh值会重算,top/bottom方案更鲁棒
真正卡住人的,从来不是怎么写那行 CSS,而是没打开开发者工具,逐层点开父元素看 computed height 到底是不是你预期的数值 —— 只要其中一层是 auto,整条链就断了,再怎么调子元素都没用。


















