移动端 vh 不准因地址栏滚动时显隐导致视口高度变化,而 vh 始终基于初始布局视口;dvh 是动态视口高度单位,ios safari 16.4+、chrome 109+等已支持。

移动端 vh 在 Safari 和 Chrome 中为什么不准?
因为浏览器地址栏(URL bar)在滚动时会隐藏或显示,导致视口高度动态变化,vh 却始终基于“初始布局视口”计算——也就是页面刚加载时的可视高度。用户一滚动,地址栏收起,实际可用高度变大,但 vh 值没变,于是元素被撑出屏幕或留白异常。
典型现象:全屏轮播图底部被截、固定定位按钮错位、height: 100vh 的弹层在 iOS Safari 上滚动后顶部露白。
dvh 是什么?哪些浏览器支持?
dvh(dynamic viewport height)是 CSS 新增的单位,代表“当前实际可用的视口高度”,会随地址栏显隐实时响应。它不是补丁,而是标准解法。
支持情况(截至 2024 年中):
- iOS Safari 16.4+、iPadOS 16.4+
- Chrome Android 109+、Desktop 109+
- Firefox Android 117+(需开启
layout.css.dvh-vw.enabled标志) - 不支持的旧版浏览器(如 iOS Safari dvh,回退到原有样式
如何安全地用 dvh 替换 vh?
不能直接全局替换,必须考虑降级和兼容性。推荐用 @supports 特性查询做渐进增强:
section.fullscreen {
height: 100vh; /* fallback */
}
@supports (height: 100dvh) {
section.fullscreen {
height: 100dvh;
}
}
关键点:
- 始终把
vh放在前面,确保不支持dvh的设备有可用值 - 避免在同一个声明块里混写
vh和dvh(如height: 100vh, 100dvh),CSS 不允许逗号分隔值 - 如果用 PostCSS 或构建工具,慎用自动转换单位插件——它们通常不识别
@supports上下文,可能把dvh错误降级
还有哪些单位也受地址栏影响?怎么处理?
dvh 只解决高度问题;同理,dvw、svh、lvh 也已进入标准:
-
dvh:动态视口高度(推荐用于大多数“占满当前可见区域”的场景) -
svh:small viewport height(地址栏展开时的高度,适合需要始终避开地址栏的 UI) -
lvh:large viewport height(地址栏收起时的最大高度,适合内容绝对不能被滚动遮挡) -
dvw同理,但宽度几乎不受影响,移动端横向滚动极少,一般无需替换
例如,一个必须始终贴底、且不被收起的地址栏顶上去的按钮:
.fixed-bottom-btn {
bottom: clamp(1rem, 5svh, 2rem); /* 用 svh 确保总在地址栏上方 */
}
真正麻烦的不是写 dvh,而是意识到某些“全屏”效果本就不该依赖视口单位——比如轮播容器高度更适合由内容撑开,再用 min-height: 100dvh 保底。地址栏行为本质不可控,能少依赖就少依赖。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











