应使用100dvh而非100svh解决工具栏遮挡问题,因100svh是固定最小可视高度、不响应滚动变化,而100dvh能实时适配地址栏收起/展开,需配合min-height: 100vh兜底及@supports检测。

别用 100svh 解决工具栏遮挡问题——它根本不是为这个场景设计的,强行替换会导致滚动后底部大面积留白或内容上浮。
为什么 100svh 会加重工具栏遮挡问题
100svh 表示“地址栏和底部工具栏都完全展开时的最小可视高度”,它是个固定锚点值,不随滚动变化。iOS Safari 中,用户一滚动,地址栏收起,实际可视区域变大,但 100svh 还卡在那个最小值上,结果就是容器高度偏小、内容悬空、底部露白。
- 典型现象:
height: 100svh的全屏轮播,下拉后顶部被截、底部空白明显 - 它 ≠ 当前可见高度,也不响应工具栏显隐,和
100vh一样“冻结” - Safari 直到 v17.4 仍不支持
svh,写了就忽略,回退到auto或上一条声明
100svh 真正该用在哪
它只适合语义明确的“必须始终避开工具栏”的固定元素,比如支付页底部按钮、输入框、弹层操作区——这些地方宁可牺牲一点空间,也不能被地址栏顶上去。
- 固定定位按钮:
position: fixed; bottom: 0; height: 100svh;(错,应是height: 60px; padding-bottom: env(safe-area-inset-bottom);) - 正确写法示例:
.pay-button { position: fixed; bottom: 0; width: 100%; padding-bottom: env(safe-area-inset-bottom); } - 不要用
@supports (height: 100svh)做降级——Safari 不识别,整条规则失效;Chrome 115+、Firefox 119+ 才支持,覆盖率有限
想撑满当前屏幕?用 100dvh,不是 100svh
100dvh 是唯一能实时响应地址栏收起/展开的单位,iOS Safari 16.4+、Chrome 109+、Firefox 117+ 已稳定支持,且语义精准:此刻用户真正看到的高度。
- 写法必须带兜底:
min-height: 100vh;放在@supports外,否则老设备直接塌陷 - 推荐用
min-height而非height,避免内容超长时被截断 - 错误示范:
height: 100svh; height: 100dvh;→ Safari 忽略前者,后者又没@supports检测,旧版直接丢高度 - 正确写法:
section.full { min-height: 100vh; }@supports (min-height: 100dvh) { section.full { min-height: 100dvh; } }
兼容 iOS 15 及微信 WebView 的兜底必须用 JS
微信内置浏览器、QQ 浏览器、iOS 15.x 等环境根本不认 dvh 或 svh,CSS 方案在此类场景下完全失效。此时唯一可靠路径是监听 resize(不是 scroll),动态设置 CSS 变量:
- 首次执行必须在
DOMContentLoaded前或同步运行,否则首屏白屏期高度就错 -
resize在 iOS 上高频触发,更新style.setProperty必须包裹requestAnimationFrame - CSS 中写
height: calc(var(--vh, 1vh) * 100),注意 fallback 单位是1vh,不是1px或空值 - 别对所有元素批量设高度,只加
data-dynamic-height的容器才更新,减少重排
真正难的不是选哪个单位,而是意识到:dvh 是现代解法,svh 是特定语义补充,而 JS 动态方案仍是目前唯一能跨平台稳定响应地址栏变化的方式——尤其当你的用户大量使用微信时。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











