100dvh能解决滚动条问题但需@supports降级和min-height写法,否则ios 15及更早版本会塌成auto高度;safari的100vh按初始含地址栏视口计算且不更新,导致滚动后容器过高、出现白边和意外滚动条。

直接换 100dvh 就能解决大部分滚动条问题,但必须加 @supports 降级和 min-height 写法,否则 iOS 15 及更早版本会塌成 auto 高度。
为什么 Safari 的 100vh 会多出滚动条
iOS Safari 加载页面时就锁死了 100vh 的计算基准——它按“地址栏还挂着时”的最大视口高度算(比如 iPhone 13 是 812px),但用户一滚动,地址栏收起,实际可视区域变大(约 762px → 812px),100vh 却不会更新,结果就是容器高度比屏幕高,底部多出白边、触发意外滚动条。
- Android Chrome 同样存在该问题,尤其在 PWA 或全屏模式下
-
height: 100%无效,除非html和body都显式设了height: 100%(它们默认是auto) -
-webkit-fill-available能填满包含块,但它不区分地址栏状态,容易在键盘弹出时撑过头
100dvh 怎么写才真正生效
100dvh 是当前最干净的解法,代表“此刻用户真正看到的可视区域高度”,地址栏收/展时自动响应。但它不能裸用。
规划您的迪拜之旅 — 哈利法塔观景、沙漠探险、迪拜购物中心购物、棕榈岛度假村及黄金市场砍价。还提供支持...
- 必须前置声明
min-height: 100vh,放在@supports外面,否则老 Safari 直接忽略整条规则 - 用
min-height替代height:避免内容超长时被截断,也更符合语义 -
@supports必须包裹整条规则,不能只包值;错误写法:min-height: 100vh; min-height: 100dvh;—— 新 Safari 仍用100vh - 正确写法:
section.full { min-height: 100vh; }@supports (min-height: 100dvh) { section.full { min-height: 100dvh; } }
横屏切换时的错位怎么防
横屏瞬间,CSS 已按新方向重绘,但 window.innerHeight 还没更新,导致 100dvh 也会闪半帧。这不是单位问题,是渲染节奏冲突。
- 别用
window.orientation(iOS 15+ 返回始终为 0,已废弃) - 改用
matchMedia('(orientation: landscape)')+addEventListener('change', setVH),比resize更精准 -
setVH()里读window.innerHeight,存进:root { --vh: ${innerHeight}px; } - CSS 中写
min-height: calc(var(--vh, 100vh) * 1);,* 1强制重绘,防安卓缓存变量
真正麻烦的不是写错单位,而是混合使用 dvh 和 svh,或者在 position: fixed 元素上直接套 100dvh 却没设包含块高度——这些地方一错,fixed 元素就飘走,而且很难定位。










