应使用min-height: 100dvh替代100vh,并前置min-height: 100vh兜底,配合@supports (min-height: 100dvh)包裹覆盖规则;因100vh按初始含地址栏的布局视口静态计算,不随滚动更新,导致ios/android浏览器出现白边、fixed错位或滚动条,而100dvh动态响应可视区域变化,但需降级兼容ios 15及微信x5等不支持环境。

直接用 min-height: 100dvh 替代 height: 100vh,但必须加 min-height: 100vh 降级兜底,否则在 iOS 15、微信 X5 内核等环境会塌陷成 auto 高度。
为什么 100vh 在 iOS Safari 和 Android Chrome 里会多出一截
浏览器把地址栏、底部工具栏的高度也算进“视口”了——它按最大可能高度算,不是你此刻看到的区域。比如 iPhone 14 初始加载时 window.innerHeight 是 700px,但 100vh 却被解析为 844px(物理屏高),结果就是底部白边、fixed 元素错位、滚动条意外出现。
- 这不是 bug,是早期 CSS 规范对“viewport”定义没覆盖动态工具栏场景
-
100vh值在页面加载瞬间就锁死,滚动时地址栏收起,100vh不更新 -
height: 100%无效,除非html和body都显式设了height: 100%,而它们默认是auto
怎么安全地用 100dvh 替代 100vh
100dvh 是动态单位,始终等于当前可见区域高度的 100%,地址栏收/展时自动响应。但它不能直接写 height: 100dvh,否则旧环境会忽略整条声明,导致容器塌陷。
- 必须用
min-height:优先写min-height: 100vh,再用@supports (min-height: 100dvh)覆盖 - 禁止逗号分隔单位:
min-height: 100vh, 100dvh是非法语法,CSS 直接丢弃整条规则 - 构建工具(如 PostCSS)若自动把
dvh降级为vh,必须关掉该功能,否则白忙一场 - 不要用
height: 100dvh—— 它会把内容撑满且不可滚动,用户滑不到下面
微信、iOS 15 等不支持 dvh 的环境怎么办
CSS 方案在此类场景完全失效,JS 是唯一可靠路径。但监听目标不能是 resize:iOS 地址栏收起时不触发 resize,只触发 scroll 或 visualViewport?.resize。
- 首次执行要同步运行,在
DOMContentLoaded前或刚进脚本就调用,否则首屏白屏期高度就错 - 设 CSS 变量:
document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`) - CSS 中统一用:
min-height: calc(var(--vh, 1px) * 100),不依赖父级height: 100% - 监听事件组合建议:
visualViewport?.resize(iOS 最准) +scroll+orientationchange
容易被忽略的关键点:getComputedStyle(el).height 返回的是字符串 "100dvh",无法用于 JS 计算;@media (min-height: 100dvh) 语法非法;如果父容器是 display: contents 或某些 Flex 场景,子元素即使写了 100dvh 也可能卡住不动。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











