不能直接用100dvh替代100vh,因旧版safari和微信x5内核会忽略整条规则致高度塌陷;必须用@supports包裹规则块,min-height优先于height,绝对定位元素应改用top/bottom,js兜底需同步执行并监听scroll与weixinjsbridgeready。

直接用 100dvh 替代 100vh 不能解决问题,反而会让旧版 Safari 和微信 X5 内核直接忽略整条规则,导致容器高度塌陷为 auto —— 这是线上最常见的白屏或布局错乱根源。
为什么不能只写 height: 100dvh
旧版浏览器(如 iOS 15.x、微信安卓 v6.x)根本不识别 dvh 单位,遇到未知单位会跳过整条声明,而不是降级到前一条。比如:
.page { height: 100vh; height: 100dvh; }
结果是:所有不支持 dvh 的环境都只执行第一行,问题照旧;而新 Safari 又因 CSS 层叠规则,100dvh 被后写但没被包裹,仍可能被错误覆盖。
- 必须用
@supports (min-height: 100dvh)包裹整个规则块,不能只包值 - 兜底声明(如
min-height: 100vh)必须写在@supports外部,确保老环境至少有基础高度 - 优先用
min-height,避免内容超长时被截断;height: 100dvh会锁死高度,不可滚动
min-height: 100dvh 在绝对定位元素里失效?
绝对定位元素的百分比高度(包括 100dvh)依赖包含块(containing block)的高度。如果父容器没设显式高度或 min-height,100dvh 计算结果就是 0。
- 别对
position: absolute元素写height: 100dvh,改用top: 0; bottom: 0; - 确保其最近的非
static定位祖先(如body或弹窗容器)已设min-height: 100dvh - 若父容器本身靠
--vh驱动,需确认 JS 已先完成初始化,否则子元素读到的是初始1px
微信和 iOS 15 怎么兜底?JS 方案绕不开
微信 X5 内核、iOS 15.x 等环境完全不支持 dvh,CSS 方案在此类场景彻底失效。JS 是唯一可靠路径,但关键点极易遗漏:
- 首次执行必须同步运行,在
DOMContentLoaded触发前或刚进脚本就调用,否则首屏渲染用的是地址栏未收起时的错误高度 - 监听目标不能只靠
resize:iOS 地址栏收起时不触发resize,只触发scroll;微信还需监听weixinjsbridgeReady - 防抖必须用
requestAnimationFrame,setTimeout在微信安卓下会导致高度卡死 - CSS 中统一用
min-height: calc(var(--vh, 1px) * 100),不依赖父容器是否设了height: 100%
真正容易被忽略的是:即使你写了 @supports (min-height: 100dvh),也要检查父容器是否参与高度继承链;而一旦引入 JS 方案,requestAnimationFrame 防抖和首次同步执行这两个点,漏掉任何一个都会导致首屏白屏或滚动跳变。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











