100vh在移动端因地址栏动态显隐导致高度计算错误,而100dvh是动态视口高度单位,能实时响应地址栏变化,Chrome 105+、Safari 16.4+、Firefox 112+已支持,写法同100vh。

直接用 height: 100vh 即可让元素视觉上撑满视口高度,但要注意它不等于“内容区域全屏”,尤其在移动端或有地址栏的场景下会出错。
为什么 100vh 在手机上经常“过高”或“过矮”
移动浏览器的地址栏会动态显示/隐藏,vh 单位基于初始视口计算,后续滚动时不会重算。Safari(iOS)和部分 Android 浏览器中,地址栏收起后视口变高,但 100vh 仍按收起前的高度渲染,导致底部留白或内容被截断。
- Chrome on Android:地址栏展开时,
100vh可能比实际可视区域高约 60–80px - iOS Safari:地址栏收起后,
100vh仍按“带地址栏”的高度计算,造成底部空白 - 解决思路不是禁用
vh,而是用它做基础,再用 JS 或 CSS 机制补偿
更稳妥的替代方案:100dvh(推荐优先尝试)
100dvh 是“动态视口高度”单位,浏览器会实时响应地址栏显隐变化,目前 Chrome 105+、Safari 16.4+、Firefox 112+ 已支持。它比 100vh 更贴近真实可用高度。
- 写法完全一致:
height: 100dvh,无需 JS - 兼容性需检查:旧版 iOS Safari(
- 注意:CSS 中声明顺序很重要,
100dvh必须写在100vh后面才有效
需要兼容老浏览器?用 min-height: 100vh + height: 100% 组合
当必须支持不支持 dvh 的环境(如微信内置浏览器旧版本),纯 CSS 方案只能退而求其次:用 min-height 保底,靠父容器高度传递来逼近全屏效果。
立即学习“前端免费学习笔记(深入)”;
- 确保所有父级(
html、body、外层容器)都设height: 100% - 目标块设
min-height: 100vh,而非height: 100vh,避免内容超长时被截断 - 如果块内有 flex 布局,加
flex-shrink: 0防止被压缩 - 慎用
overflow: hidden——它会让超出部分不可见,掩盖真实高度问题
JS 补偿方案(仅当 CSS 不够用时启用)
如果页面必须精确贴合当前可视区域(例如全屏轮播、canvas 渲染),且兼容性要求极高,可监听 resize 并读取 window.innerHeight 动态设置内联样式:
function updateVh() {<br> document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`);<br>}<br>window.addEventListener('resize', updateVh);<br>updateVh();然后在 CSS 中:height: calc(var(--vh, 1vh) * 100);。这个方案有效,但引入了运行时依赖,且 resize 频繁触发可能影响性能。
真正难处理的从来不是“怎么写满屏幕”,而是“怎么在地址栏进出、键盘弹起、横竖屏切换这些真实操作中保持稳定”。100dvh 是目前最接近开箱即用的解,但别忘了给它配一个 100vh 回退——否则 iOS 16.3 用户打开你的页面,第一眼看到的就是大片空白。


















