不能,必须用@supports(min-height:100dvh)包裹整条规则并兜底min-height:100vh,因iOS15及更早、微信WebView等环境不支持dvh会丢弃声明导致塌陷。

100dvh 能直接替换 100vh 吗?不能,必须加 @supports 检测
直接写 min-height: 100dvh 在 iOS 15 及更早、微信内置 WebView(截至 2026 年 5 月)、QQ 浏览器等环境会解析失败,整条 CSS 声明被丢弃,退回到无高度控制状态——页面可能塌陷或留白。
稳妥写法是先兜底 100vh,再用 @supports 升级:
.full-height {
min-height: 100vh;
}
@supports (min-height: 100dvh) {
.full-height {
min-height: 100dvh;
}
}-
@supports必须精确匹配语法:(min-height: 100dvh)有效,(height: 100dvh)无效(height不支持dvh) -
@supports (dvh: 1px)是非法检测,浏览器不识别,别写 - 微信环境必须 JS fallback,纯 CSS 不够用
svh / lvh / dvh 语义完全不同,混用会错乱
看到 100svh 就以为是“更小的 dvh”?错。三者基准不同,不能互换,也不能叠加使用。
-
100svh= 地址栏**强制显示时**的最小可用高度 → 适合支付页底部按钮、弹窗确认区(确保永远不被遮挡) -
100lvh= 地址栏**强制隐藏时**的最大高度 → 适合全屏视频、Canvas 绘图(但滚动初期顶部可能被盖住) -
100dvh= 当前**实时可视区域高度** → 适合轮播图容器、固定底栏(滚动时自动响应) - 在同一个组件里同时写
height: 100dvh和padding-bottom: 10svh,数值基准不一致,结果不可预测
监听 scroll 无法更新视口高度?因为触发的是 resize
iOS Safari 地址栏显隐不触发 scroll,而是触发 resize 事件。只监听 scroll 会导致高度滞后甚至完全不更新。
立即学习“前端免费学习笔记(深入)”;
- 正确做法:监听
resize+orientationchange(横竖屏切换) - 若需 JS fallback,必须用
requestAnimationFrame节流更新--dvh自定义属性 - 不要依赖
window.innerHeight直接赋值——它在某些 Android WebView 中返回的是设备物理高度,非可视高度 - 真机测试比模拟器更重要,iOS 16.4+ 才原生支持
dvh,旧版必须降级
为什么 100vh 在移动端总是不准?因为地址栏算进去了
iOS Safari 把地址栏高度计入 100vh,导致实际可见区域变小。典型现象:固定底部按钮被盖住、全屏轮播图顶部被切掉、height: 100vh 的容器滚动后错位。
- 这不是 bug,是规范行为:
vh基于 layout viewport(布局视口),而用户看到的是 visual viewport(视觉视口) -
dvh对应的就是 visual viewport 高度,所以更贴近真实体验 - 安卓 Chrome 从 100+ 开始支持
dvh,但 WebView 兼容性不稳定,仍建议双层回退:height: 100dvh; height: calc(100 * var(--vh)); height: 100vh; - 键盘弹出时,
dvh也会动态收缩,vh则完全不变——这是选型关键差异
实际落地时最易忽略的点:微信 WebView 至今不支持 dvh,且不会触发 resize 事件,必须单独判断 UA + 手动注入高度计算逻辑。


















