必须用@supports(min-height:100dvh)包裹整条规则且兜底min-height:100vh写在外层,因iOS15及更早系统完全忽略100dvh导致高度塌陷;错误写法如连续声明或仅包值会使旧设备失效、新设备仍走100vh。

@supports 必须包裹整条规则,不能只包值
裸写 min-height: 100dvh 在 iOS 15 及更早系统中会直接被浏览器静默忽略,元素高度退化为 auto,页面视觉上“塌陷”成一条线。这不是报错,是规范行为:旧版 WKWebView 不识别 dvh 单位,整条 CSS 声明被丢弃。
错误写法:min-height: 100vh;min-height: 100dvh;
这样新 Safari 仍走 100vh,老 Safari 完全忽略第二行,问题照旧。
-
@supports必须检测min-height: 100dvh(不是height),且包裹整个选择器块 - 兜底声明(
min-height: 100vh)必须写在@supports外层,确保老环境至少有基础高度 - 优先用
min-height而非height,避免内容超长时被裁剪
JS fallback 要监听 resize + 首屏立即执行
当目标用户含大量 iOS 15.x 或微信 X5 内置浏览器时,@supports 降级后只剩 100vh,仍会因地址栏收起/键盘弹出导致高度错位。此时 JS 动态方案是唯一出路,但很多人监听 scroll,结果完全不更新——Safari 地址栏显隐只触发 resize,不发 scroll。
- 首次执行必须在
DOMContentLoaded后立即运行,否则取到的是地址栏未收起时的错误初始window.innerHeight - 只监听
resize即可(orientationchange在部分 iOS 上不可靠) - 用
requestAnimationFrame节流,避免 iOS 连续触发多次resize导致卡顿 - 设 CSS 变量时,值必须是带
px单位的数值,且是window.innerHeight * 0.01(即 1% 高度),不是直接塞vh
CSS 中 calc() 写法和 fallback 层级不能错
JS 设置了 --vh,但 CSS 里写错 calc() 就会失效。常见错误是把单位写进变量值里,或 fallback 用了相对单位——calc() 无法对 1vh 这类相对值做数学运算。
- JS 中:
document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`) - CSS 中正确写法:
min-height: calc(100 * var(--vh, 1px))(1px是绝对单位兜底) - 错误写法:
calc(var(--vh, 1vh) * 100)(1vh无法参与计算) - 完整 fallback 链应为:
min-height: 100vh;→@supports→min-height: calc(100 * var(--vh, 1px))
绝对定位元素用 dvh 容易失效,top/bottom 更可靠
给 position: absolute 元素写 min-height: 100dvh,但父容器没设高度(比如只是 position: relative 且无 height),它不会“撑满屏幕”,而是按包含块计算,结果常为 0。
- 根本原因:
100dvh是百分比类单位,依赖祖先高度上下文,不是全局强制占满 - 更稳妥的做法是改用
top: 0; bottom: 0;(前提是父容器为relative或fixed) - 若必须用
--vh,要确保父容器已先完成初始化,否则子元素读到的是初始1px - 别信
-webkit-fill-available:它对min-height无效,也不响应软键盘
实际最难的从来不是代码怎么写,而是哪些机型要切 JS、哪些事件要监听、哪一层 fallback 该用 1px 还是 1vh——漏掉任意一个,用户一滑动,视口就断层。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











