唯一合法检测方式是@supports (min-height: 100svh)或@supports (min-height: 100lvh),因svh/lvh仅允许用于min-height;二者语义不同:100svh是地址栏强制显示时最小安全高度,100lvh是强制隐藏时最大可能高度,不可混用或替代100vh。

@supports 必须用 min-height 检测 svh/lvh
直接写 @supports (height: 100svh) 或 @supports (svh: 1px) 完全无效——前者因 svh 不被允许用于 height,后者语法非法,所有浏览器都会跳过整块规则,导致降级失效。唯一合法写法是:@supports (min-height: 100svh) 或 @supports (min-height: 100lvh)。
svh/lvh 不能当 100vh 的“平替”来用
100svh 是地址栏**强制显示时的最小安全高度**,100lvh 是地址栏**强制隐藏时的最大可能高度**,二者都是固定锚点值,不随滚动或键盘弹起实时变化。混用会出布局错乱:
- 把
100vh全换成100svh→ 工具栏收起后大量留白 - 全换成
100lvh→ 工具栏展开时内容被截断 - 在同一个组件里同时用
min-height: 100dvh和padding-bottom: 10lvh→ 基准不同,结果不可预测
微信、iOS 15 及更早、QQ 浏览器必须 JS fallback
CSS 层面的 svh/lvh 在微信 X5 内核(截至 2026 年 5 月)、iOS 15.x、多数安卓 WebView 中压根不识别,@supports 检测返回 false,整条声明被丢弃。JS 是唯一可靠路径,但注意:
- 监听目标必须是
visualViewport?.resize(iOS 最准)或resize+scroll+orientationchange组合,仅监听scroll会漏掉地址栏显隐事件 - 首次执行必须在
DOMContentLoaded前或刚进脚本就调用,否则首屏高度就错 - 设 CSS 变量:
document.documentElement.style.setProperty('--svh', `${window.innerHeight * 0.01}px`) - CSS 中统一用:
min-height: calc(var(--svh, 1px) * 100),不依赖父级height: 100%
保底结构要分层,不能只靠一个单位
真正能兜住各种环境的写法是三层嵌套,缺一不可:
- 最外层:基础保底 ——
min-height: 100vh(覆盖所有支持vh的环境) - 中间层:
@supports (min-height: 100dvh)→ 升级为min-height: 100dvh(解决滚动/键盘导致的高度跳变) - 最内层:
@supports (min-height: 100svh)→ 仅对支付页底部按钮、弹窗确认区等**必须永远可见**的区域启用min-height: 100svh,且需 JS 同步 fallback
别指望一个单位通吃;svh 和 lvh 是语义专用单位,不是兼容补丁。最容易被忽略的是:它们在 @media 查询里完全不可用,也拿不到像素值,getComputedStyle(el).minHeight 返回的仍是字符串 "100svh",没法用于 JS 计算。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











