100vh在移动端“不准”是因为它基于布局视口而非实时可视区域,ios safari等浏览器加载时按最大高度计算且不响应地址栏/键盘变化;应优先用100dvh并配合@supports(min-height: 100dvh)降级至100vh,微信webview等旧环境需js监听resize动态设置--vh变量。

100vh 在移动端为什么经常“不准”
因为 100vh 取的是浏览器**理论上能撑开的最大视口高度**,不是你当前看到的可用区域。iOS Safari、Chrome Android、微信 WebView 都这样:页面刚加载时地址栏还在,100vh 却按“地址栏收起后”的高度算,结果内容被截断;滚动后地址栏隐藏,100vh 不变,但实际可视区变大,留出空白。这不是 bug,是规范定义如此。
svh / lvh / dvh 各自解决什么问题
三者不是“升级版 vh”,而是针对不同场景设计的独立单位:
-
100svh= 地址栏**强制显示时**的最小可用高度 → 适合底部固定按钮、支付确认区,确保永远不被遮挡 -
100lvh= 地址栏**强制隐藏时**的最大可用高度 → 适合全屏视频、Canvas、沉浸式画布,但初始加载可能被顶部地址栏盖住 -
100dvh= 当前**实时可视区域高度** → 适合轮播容器、带固定底栏的列表页,滚动时自动缩放,最接近开发者直觉里的“真 100vh”
混用会出错:比如 height: 100dvh + padding-bottom: 20svh,两个单位基准不同,结果不可控。
@supports 检测必须写对,否则直接失效
@supports (min-height: 100dvh) 是唯一合法写法。常见错误:
- 写成
@supports (height: 100dvh)→height不支持dvh,检测永远 false - 写成
@supports (dvh: 1px)→ 语法非法,浏览器直接忽略整条@supports块 - 漏掉兜底:没写
min-height: 100vh就直接上100dvh→ iOS 15 及更早、微信 WebView(截至 2026 年 5 月)、QQ 浏览器等环境会丢弃整条声明,高度退化为 auto
正确姿势:
.full-height {
min-height: 100vh;
}
@supports (min-height: 100dvh) {
.full-height {
min-height: 100dvh;
}
}
微信和部分安卓 WebView 必须 JS fallback
CSS 层面的 dvh 在微信内置浏览器里至今不识别(2026 年 5 月实测),@supports 检测失败,纯 CSS 方案彻底失效。这时候得靠 JS:
- 监听
resize和scroll,用window.innerHeight动态设置内联样式 - 注意防抖:频繁触发
resize会导致重排,建议节流到 100ms 以上 - 别只依赖
innerHeight:某些安卓 WebView 下它不随地址栏变化更新,得结合visualViewport?.height判断
真正麻烦的不是写法,而是不同 WebView 对 visualViewport 的支持程度不一 —— 这块必须实机测试,模拟器容易误判。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











