应优先使用100dvh替代100vh,因其能随键盘弹出、地址栏显隐动态调整高度;但需用@supports检测并为不支持的旧版安卓Chrome提供降级方案。

100vh 在安卓 Chrome 里“不准”,不是你写错了,是它根本没考虑键盘弹出后的可视区域变化——必须换用 100dvh 或降级方案。
安卓 Chrome 中 100vh 为什么总遮住底部内容
安卓 Chrome(尤其是 100+ 版本)把 100vh 算作「整个屏幕高度」,而非用户当前能看见的高度。当软键盘弹出时,视口被压缩,但 100vh 值不变,导致:
- 固定定位的按钮(如
position: fixed; bottom: 0)直接被键盘盖住 - 全屏表单容器仍按满屏渲染,输入框实际不可见
- 滚动后地址栏收起,
100vh也不更新,布局错位
这不是 bug,是规范行为:vh 是静态单位,只读取初始 window.innerHeight 一次。
优先用 100dvh 替代 100vh,但必须加 @supports 降级
100dvh 是专为这种场景设计的动态单位,Chrome 100+ 已原生支持,会随键盘/地址栏显隐自动重算高度。
直接替换不安全,因为旧版安卓 Chrome(dvh,会直接丢弃该声明:
- 只写
height: 100dvh→ 不支持的浏览器失去高度控制,内容塌缩 - 正确写法是叠加 fallback:
.full-screen { height: 100vh; height: 100dvh; } - 更稳妥用
@supports包裹:.full-screen { height: 100vh; } @supports (height: 100dvh) { .full-screen { height: 100dvh; } }
别混淆 dvh、svh 和 lvh 的使用场景
这三个新单位都响应动态视口,但语义不同,混用容易出错:
-
100dvh= 当前「实际可见区域」高度(推荐用于全屏容器、固定底部按钮) -
100svh= 工具栏「显示时」的最小可视高度(适合可滚动内容区,配合max-height+overflow-y: auto) -
100lvh= 工具栏「隐藏时」的最大可视高度(适合首屏大图、需要撑满的 landing 页) - 错误示例:
height: calc(100dvh - env(keyboard-inset-bottom))——dvh已含键盘影响,再减env()会导致过度收缩
安卓 WebView 或低版本 Chrome 必须用 JS fallback
如果你的应用跑在安卓 WebView(比如 Cordova、Capacitor)或 Chrome dvh 不可用,得手动同步可视高度:
- 监听
resize、scroll(iOS 地址栏变化不触发 resize)、focus(键盘弹出时机) - 用
visualViewport?.height获取实时可视高度(比window.innerHeight更准,但 Android WebView 支持度差) - 退而求其次:监听
focus后延时 100ms 读window.innerHeight,存为 CSS 变量:document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`); - CSS 中使用:
height: calc(var(--vh, 1vh) * 100),并保留height: 100vh作为最老浏览器兜底
真正难的不是“怎么设高度”,而是“什么时候重设”——键盘弹出、地址栏收起、横竖屏切换,三者触发机制完全不同,不能只靠 resize。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











