应优先使用100dvh实现动态视口适配,但必须通过@supports (min-height: 100dvh)检测并回退至100vh;svh/lvh适用于固定场景,不可混用;微信等不支持环境需JS监听resize事件动态设置--vh变量兜底。

直接用 100dvh 替代 100vh 会出问题,必须配合兼容性检测和降级策略。移动端高度跳动的本质是浏览器地址栏显隐导致可用视口实时变化,而 vh 是静态计算、不响应变化。dvh、lvh、svh 各有定位,不能混用或随意替换。
优先用 dvh 做动态适配,但必须加 @supports 检测
100dvh 是最接近“当前真实可视区域”的单位,滚动时自动跟随地址栏收放调整高度,能从根本上缓解跳动。但它不是全平台可用:
- iOS 15 及更早版本不支持
- 微信内置 WebView(截至 2026 年 5 月)完全不认识
dvh,CSS 解析失败会丢弃整条声明 -
@supports必须写成@supports (min-height: 100dvh),写成(height: 100dvh)或(dvh: 1px)都无效
正确写法:
.full-height {<br> min-height: 100vh; /* 兜底:所有环境都认 */<br>}<br>@supports (min-height: 100dvh) {<br> .full-height {<br> min-height: 100dvh; /* 仅支持环境生效 */<br> }<br>}svh 和 lvh 不是 dvh 的“替补”,而是固定锚点值
它们不会跳变,但也不动态更新,适用场景明确且互斥:
-
100svh= 地址栏强制展开时的最小高度 → 适合底部操作按钮、弹窗确认区,确保永远不被顶起 -
100lvh= 地址栏强制隐藏时的最大高度 → 适合启动页、广告全屏页、Canvas 绘图,追求物理屏幕最大填充 - 不要在一个元素里混用
dvh和svh(比如height: 100dvh; padding-bottom: 20svh),基准不同,结果不可控
微信等不支持环境必须 JS fallback
纯 CSS 无法覆盖微信 WebView。需监听 resize 事件(注意:不是 scroll,iOS Safari 地址栏显隐触发的是 resize):
- 在页面加载和每次
resize时,读取window.innerHeight - 将该值设为自定义 CSS 变量,例如
:root { --vh: 812px; } - CSS 中用
min-height: calc(var(--vh, 1vh) * 100)作为兜底逻辑 - 注意键盘弹出也会触发
resize,需做防抖处理
别忽略初始布局和 meta viewport 设置
再新的单位也依赖基础视口配置:
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">必须存在,尤其viewport-fit=cover对刘海屏和地址栏行为有影响 - 避免设置
user-scalable=no,它会干扰地址栏自动隐藏逻辑 - 部分安卓浏览器在横屏/竖屏切换时
dvh更新滞后,建议配合orientationchange事件重设


















