100vh在移动端按最大视口高度(地址栏收起时)计算,而非用户当前可见高度,导致内容被工具栏遮挡或底部留白;应优先使用min-height: 100dvh并配合@supports检测与min-height: 100vh降级。

100vh 的计算基准不是用户当前看到的高度
移动端 100vh 永远按「最大可能视口」(即地址栏和底部工具栏全部收起时的高度)计算,而不是你此刻滚动中实际可见的区域。比如 iPhone 13 屏幕物理高度是 812px,但刚加载页面时地址栏展开,window.innerHeight 只有约 762px;而 100vh 仍被解析为 812px —— 这多出来的 ~50px 就会直接加到元素总高度里,导致内容被推到工具栏下方、被遮挡。
盒模型叠加 padding/border 后溢出更明显
默认 box-sizing: content-box 下,min-height: 100vh 只控制内容区高度,padding 和 border 会额外增加总高度。例如:
div {
min-height: 100vh;
padding: 20px;
border: 1px solid #ccc;
}
此时元素总高度 = 100vh + 40px(上下 padding)+ 2px(上下 border),必然超出一屏,触发垂直滚动条或内容截断。
- 即使只加
padding-top: 16px,也足以让原本刚好撑满的布局在 iOS 上出现底部白边 -
height: 100%不起作用,除非html和body都显式设了height: 100%,而它们默认是auto - 用
overflow: hidden压制只是掩盖问题,无法解决 fixed 元素错位、flex 居中失效等连锁反应
为什么不能直接换 height: 100dvh?
100dvh 是语义正确的解法,它始终等于当前视觉视口高度,地址栏收/展时自动响应。但它有现实兼容瓶颈:
- iOS 15 及更早版本、旧版 Samsung Internet、多数微信 WebView 会完全忽略
100dvh,导致元素高度塌陷为auto - 必须用
min-height而非height:避免内容超长时被裁剪 -
@supports (height: 100dvh)必须包裹,且min-height: 100vh要写在@supports外层,否则老设备连降级方案都拿不到 -
@media查询里不能用100dvh,比如@media (min-height: 100dvh)是非法语法
真正要盯住的两个细节
一是全局重置盒模型:*, *::before, *::after { box-sizing: border-box; },否则任何 padding 都可能悄悄加高元素;二是 100dvh 必须配合 min-height: 100vh 降级,且声明顺序不能反——这一步漏掉,iOS 15 用户看到的就是一片空白,而不是“稍矮一点”的页面。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











