应使用 min-height: 100vh 同时设置 html 和 body 元素,而非 height;因 100vh 直接映射视口高度、语义明确,而 height 会截断内容,100% 则易因父级无高度而失效。

用 min-height 控制文档最小高度,不是 height
HTML 文档本身没有“最小长度”属性,真正起作用的是 CSS 的 min-height。直接给 或 设 min-height: 100vh 是最常见也最可靠的方案。设 height: 100vh 反而容易导致内容被截断——因为它是强制高度,不随内容伸缩。
常见错误现象:body 高度不够,底部留白;或设置了 height: 100% 却没生效,页面撑不满视口。
-
和都需显式设min-height: 100vh,否则子元素的百分比高度会失效 - 避免只设
body { min-height: 100vh; }而忽略html,尤其在旧版 Safari 中可能不生效 - 若页面有固定页脚,
min-height比height更安全——内容多时能自然撑开,不会遮挡或溢出
为什么 100vh 比 100% 更稳
100% 是相对父容器高度计算的,而 的父容器是视口,但规范中它默认没有“高度”,所以 body { height: 100% } 常常算出来是 0。而 100vh 直接表示视口高度的 100%,语义清晰、行为确定。
使用场景:登录页、后台布局、全屏卡片等需要“至少一屏高”的页面。
立即学习“前端免费学习笔记(深入)”;
-
vh单位兼容性好(IE9+),无需 polyfill - 移动端 Safari 在地址栏收放时会重算
vh,若出现跳动,可用100dvh替代(Chrome 105+/Safari 16.4+ 支持) - 不要混用
%和vh在同一层布局逻辑里,容易因继承链断裂导致高度塌陷
min-height 设在哪一层才真正生效
必须同时作用于 和 ,且不能被其他样式覆盖。很多人只设了 body,结果发现无效——因为 html 默认高度由内容决定,body 的 min-height 缺少基准。
可这样写:
html, body {
margin: 0;
padding: 0;
min-height: 100vh;
}- 如果用了 CSS Reset 或 Normalize,检查是否重置了
html或body的height/min-height - 框架如 Vue/React 的根容器(如
#app)若没继承高度,也要单独设min-height: 100%或100vh - Flex 布局中,父容器设
display: flex; min-height: 100vh;后,子项用flex: 1才能占满剩余空间
移动端 vh 动态变化带来的坑
Safari 地址栏收起/展开时,vh 值会变(比如从 100vh → 108vh),导致页面突然拉伸或压缩。这不是 bug,是浏览器对可视区域的真实反馈,但 UI 往往不希望这样。
- 优先考虑用
100dvh(dynamic viewport height),它始终取“当前最大可用高度”,避开地址栏影响 - 若需兼容老浏览器,可用 JS 监听
resize并动态更新style.setProperty('--vh', `${window.innerHeight * 0.01}px`),再用min-height: calc(var(--vh, 1vh) * 100) - 慎用
position: fixed+top: 0; bottom: 0模拟全高——它会脱离文档流,影响滚动和可访问性
真正难的不是设最小高度,而是判断“谁该负责撑高”以及“高度变化时要不要响应”。多数情况下,老老实实用 html, body { min-height: 100vh; } 就够了,除非你正被 Safari 的地址栏搞崩溃。











