100dvh不能直接替换100vh,必须用@supports(min-height:100dvh)包裹整条规则并兜底min-height:100vh,否则ios15及更早、微信webview等不支持环境会丢弃声明导致高度塌陷。

100dvh 不能直接替换 100vh
直接写 min-height: 100dvh 会炸——iOS 15 及更早、微信内置 WebView(截至 2026 年 7 月仍不支持)、QQ 浏览器等环境根本不认识这个单位,CSS 解析失败后整条声明被丢弃,元素高度塌陷成 auto。
必须用 @supports 检测兜底:
.full-height {
min-height: 100vh;
}
@supports (min-height: 100dvh) {
.full-height {
min-height: 100dvh;
}
}
-
@supports必须精确匹配:写成@supports (height: 100dvh)无效,因为height不支持dvh,只允许用于min-height和max-height - 别用
@supports (dvh: 1px)—— 这不是合法语法,浏览器直接忽略 - Safari 16.4–17.2 存在首屏渲染时机问题:刚加载时地址栏状态未稳定,
100dvh可能短暂取错值,导致闪动
svh 和 lvh 不是 dvh 的“降级”或“备选”
svh、lvh、dvh 语义完全不同,混用等于自找麻烦。
-
100svh= 地址栏**强制显示时**的最小可用高度,适合支付页底部按钮、确认弹窗这类“绝不能被遮挡”的固定区域 -
100lvh= 地址栏**强制隐藏时**的最大高度,适合全屏视频、Canvas 绘图,但滚动初期顶部可能被地址栏盖住 -
100dvh= 当前**实时可视区域高度**,适合轮播容器、固定底栏,滚动时自动响应 - 同一组件里同时写
height: 100dvh和padding-bottom: 10svh,基准不同,结果不可预测
同时用多个单位时必须分别检测
svh、lvh、dvh 是独立特性,彼此不互为子集,不能共用一个 @supports 块。
- 错误写法:
@supports (min-height: 100dvh), (min-height: 100svh)—— 多条件是“与”关系,任一不支持整块失效 - 正确写法是各自独立检测:
.safe-bottom { height: 100vh; }
@supports (min-height: 100svh) {
.safe-bottom { height: 100svh; }
}
.fullscreen { height: 100vh; }
@supports (min-height: 100lvh) {
.fullscreen { height: 100lvh; }
}
微信等 WebView 环境必须 JS fallback
仅靠 CSS 无法覆盖微信、部分安卓壳等环境,它们即使底层 Chromium 版本够新,WebView 层也常禁用这些单位。
- 监听
resize事件(不是scroll)+ 节流,动态设置内联样式或 CSS 变量 - 注意:iOS Safari 首次触发
resize可能滞后,需加一次初始计算 - 推荐用
window.visualViewport?.height获取当前可视高度,比window.innerHeight更准(后者包含地址栏) - 不要依赖
orientationchange,它不反映地址栏变化
真正麻烦的地方不在语法,而在不同 WebView 对标准的实现差异——哪怕你写了三套 @supports,微信里照样没用,这时候 JS 就是唯一出路。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











