100dvh能解决移动端100vh静态计算导致的留白或错位问题,但需搭配min-height: 100vh降级和@supports检测,iOS 15、微信X5等不支持环境须用JS监听visualViewport.resize动态设置--vh变量。

直接用 100dvh 替代 100vh 能解决大部分问题,但必须搭配 min-height 和 @supports 降级,否则在 iOS 15、微信 X5 内核等环境中会塌成 auto 高度。
为什么 100vh 在移动端会算错
100vh 是页面加载瞬间锁定的静态值,基于“地址栏还挂着时”的最大视口高度计算。iOS Safari 加载时地址栏占约 80–120px,1vh 就按这个大高度算;用户一滚动,地址栏收起,实际可视区域变高,但 100vh 像素值不变——结果容器比屏幕高,底部留白、滚动条意外出现、position: fixed 元素错位。
Android Chrome 同样存在,尤其软键盘弹出时 window.innerHeight 突然缩水,100vh 却不更新。
- 不是你 CSS 写错了,是浏览器规范早期没覆盖动态工具栏场景
-
100svh和100lvh不是解:它们是固定锚点值,不响应滚动,强行替换只会让留白或裁切更明显 -
height: 100%无效,除非html和body都显式设了height: 100%(默认是auto)
用 100dvh 的正确写法
100dvh 表示“此刻用户真正看到的可视区域高度”,iOS Safari 16.4+、Chrome 109+、Firefox 117+ 已稳定支持,但它不能裸用。
立即学习“前端免费学习笔记(深入)”;
- 必须前置声明
min-height: 100vh,放在@supports外面,否则老 Safari 直接忽略整条规则,高度塌陷 - 用
min-height替代height:避免内容超长时被强制裁剪,也更符合语义 - 错误写法:
min-height: 100vh; min-height: 100dvh;—— 新 Safari 仍用100vh,因为 CSS 不支持逗号分隔单位 - 正确写法:
.full {<br> min-height: 100vh;<br>}<br>@supports (min-height: 100dvh) {<br> .full {<br> min-height: 100dvh;<br> }<br>} - 构建工具(如 PostCSS)若自动把
dvh降级为vh,必须关掉该功能,否则白忙一场
微信和 iOS 15 等不支持 dvh 的环境怎么兜底
微信内置浏览器(X5 内核)、iOS 15.x、部分安卓 WebView 根本不识别 dvh,CSS 方案在此类场景完全失效。JS 是唯一可靠路径,但监听目标不能只是 resize。
- iOS 地址栏收起时不触发
resize,只触发scroll;软键盘弹出时resize基本不触发 - 必须监听
visualViewport?.resize(iOS 最准),降级 fallback 到resize+scroll+orientationchange - 首次执行必须在
DOMContentLoaded后立即调用,否则首屏渲染仍用错误值 - JS 中写:
document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`) - CSS 中统一用:
min-height: calc(var(--vh, 1px) * 100),--vh必须是px单位,不能是vh(calc(var(--vh, 1vh) * 100)无效) - 微信环境还要监听
weixinjsbridgeReady,确保 X5 环境就绪
容易被忽略的关键点
真正麻烦的不是写错单位,而是混合使用 dvh 和 svh,或者在 position: fixed 元素上直接套 100dvh 却没设包含块高度——这些地方一错,fixed 元素就飘走,而且很难定位。
-
position: absolute元素依赖包含块高度,不是视口高度;若父容器没设height: 100%,100dvh实际不生效 - 更可靠做法:
top: 0; bottom: 0;直接撑满,不依赖高度计算 -
getComputedStyle(el).height返回的是字符串"100dvh",无法直接用于 JS 运算 - 服务端渲染(SSR)页面首次 hydration 前,
--vh是未定义的,必须在客户端 JS 执行后重设,否则布局闪动 - 横屏切换时,
window.innerHeight可能滞后于 CSS 重绘,导致半帧错位;改用matchMedia('(orientation: landscape)')更精准


















