应使用100dvh替代100vh解决iOS Safari地址栏收起/展开导致的可视区域变化问题,需配合@supports检测和100vh回退,因iOS 15及更早版本、微信WebView等不支持dvh。

为什么100vh在移动端会错位
因为 iOS Safari 和 Android Chrome 的地址栏滚动时会收起/展开,window.innerHeight 实时变化,但 100vh 始终按页面加载时的初始视口高度计算。结果就是:滚动后容器高度没变,但可视区域变高了,底部留白或内容被截断。
直接用100dvh前必须检查兼容性
100dvh 是当前最接近“开箱即用”的解法,但它不是万能 fallback:
- iOS Safari 16.4+、Chrome 109+、Edge 109+ 支持;iOS 15 及更早版本完全不识别该单位
- 微信内置 WebView、QQ 浏览器等国产壳多数未透出
dvh支持(截至 2026 年 5 月) - 即使支持,首次渲染时可能因浏览器内部时机问题导致首屏闪动(尤其 Safari 16.4–17.2)
- 必须搭配
@supports检测 +100vh回退,否则旧环境会丢失高度控制
稳妥写法:
.full-height {
min-height: 100vh;
}
@supports (min-height: 100dvh) {
.full-height {
min-height: 100dvh;
}
}
svh 和 lvh 不是“备用方案”,而是明确场景选择
别把 svh/lvh 当作 dvh 的降级——它们语义完全不同:
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
-
100svh= 地址栏**始终显示**时的最小可用高度,适合需要“绝对不被遮挡”的弹层或表单(比如支付页底部按钮) -
100lvh= 地址栏**完全隐藏**时的最大高度,适合全屏视频、画布类应用,但滚动初期内容可能被地址栏盖住 -
100dvh= 当前实时可视高度,适合大多数滚动即响应的场景(如轮播图、固定底栏) - 三者互不兼容,不能混用;
@supports也需分别检测:@supports (min-height: 100svh)
真正兜底的 JS 方案不是监听 scroll,而是监听 resize
iOS Safari 地址栏显隐会触发 resize 事件,不是 scroll。只监听 scroll 会导致高度更新延迟甚至失效。
- 在
DOMContentLoaded后立即执行一次:document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`) - 监听
resize,并加 300ms 节流(iOS 连续 resize 高频) - CSS 中必须用
calc(var(--vh, 1vh) * 100),避免变量未定义时整个计算式失效 - 注意:不要在
scroll里反复读取window.innerHeight,性能差且不准
复杂点在于:dvh 虽好,但无法覆盖所有 WebView 环境;而 JS 方案看似重,却是目前唯一能稳定跨平台响应地址栏变化的方式——尤其当你的用户大量使用微信或 QQ 内置浏览器时。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










