应使用100dvh而非100svh来适配动态视口,因dvh能实时响应地址栏显隐变化;必须用min-height配合@supports(min-height:100dvh)检测,并在外层写min-height:100vh兜底。

svh 并不能修复地址栏导致的盒子溢出
直接用 100svh 替换 100vh 不仅不能解决滚动时内容跳变或底部留白问题,反而会让情况更糟。因为 100svh 表示的是「地址栏和工具栏都强制展开时的最小可视高度」,它是个固定值,不随滚动变化。用户一滚动,地址栏收起,实际可视区域变大,但容器还卡在那个最小高度上,结果就是内容悬空、底部大片留白。
真正该用的是 dvh,不是 svh
100dvh 才是为动态视口设计的单位:它反映的是当前实时可视区域高度,地址栏收起时自动变高,展开时自动变矮。iOS Safari 16.4+、Chrome 109+、Firefox 117+ 已稳定支持。
- 必须用
min-height,不是height—— 避免内容超长时被截断 - 必须配合
@supports (min-height: 100dvh)检测,且检测语法不能写成height: 100dvh(height不支持dvh) - 兜底必须写在
@supports外层:min-height: 100vh,否则 iOS 15、微信 X5 等环境会直接丢弃整条声明,页面塌陷
svh 的唯一合法用途:固定避让,不是撑满
100svh 只适合语义明确的「宁可留空、不能被盖」场景,比如支付页底部按钮、弹窗确认区。但它不是靠 height: 100svh 实现的。
- 错误写法:
height: 100svh→ Safari 直到 v17.4 仍不支持,整条规则被忽略 - 正确做法:用
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)做降级 —— 不合法,也不起作用
兼容性差到必须 JS fallback
微信内置 WebView(截至 2026 年 5 月)、QQ 浏览器、部分安卓 WebView 完全不识别 dvh 或 svh。纯 CSS 方案在这里必然失效。
立即学习“前端免费学习笔记(深入)”;
- 监听
resize,不是scroll—— iOS 地址栏显隐只触发resize - 首次执行必须在 DOM ready 后,否则
window.innerHeight可能不准 - 设 CSS 变量要带单位:
document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`),CSS 中用calc(100 * var(--vh, 1px))
实际开发中,最容易被忽略的是:把 100svh 当成 100dvh 的降级方案,或者以为写了 @supports 就万事大吉 —— 兜底位置错、检测语法错、单位用错,任何一个都会让整个适配逻辑在关键机型上归零。


















