100vh在grid容器中会放大视口计算偏差,因其在ios safari或ipad chrome中实际值≠当前可视高度,导致1fr行高失真并触发滚动条;应改用height: 100vh; height: 100dvh;并配合viewport-fit=cover meta标签兜底兼容。

100vh 在 Grid 容器中会放大视口计算偏差
Grid 布局本身不导致滚动条,但当你把 display: grid 应用在 body 或根容器上,再配合 height: 100vh,问题就暴露得更明显:Grid 的行高分配(比如 grid-template-rows: 1fr auto)依赖父容器高度,而 100vh 在 iOS Safari 或 iPad Chrome 中实际值 ≠ 当前可视高度——它可能偏大(Chrome 算入收起的地址栏),也可能偏小(Safari 算入底部工具栏)。结果就是 Grid 计算出的 1fr 高度失真,内容被“撑开”或“压缩”,最终触发垂直滚动条。
为什么 overflow: hidden 在 Grid + 100vh 下经常失效
overflow: hidden 只作用于**该元素自身内容溢出**,但移动端滚动条往往来自 body 或 html 层级的尺寸错位。常见错误场景:
- 没重置
html和body的默认margin,哪怕只多 4px,也会让body总高度 >100vh - Grid 容器设了
height: 100vh,但子元素用了min-height: 100vh或height: 100%,形成双重叠加 - 使用
box-sizing: content-box(默认)时,padding或border会让 Grid 区域总高超出100vh
用 dvh 替代 100vh 是最简方案,但要注意声明顺序
直接把 height: 100vh 改成 height: 100dvh 能解决大部分动态视口适配问题,但必须保证兼容性兜底:
-
100dvh在 Safari 16.4+、Chrome 105+、Firefox 112+ 支持;旧版 Safari 会忽略该行,回退到前一条 - 务必把
height: 100vh写在前面,height: 100dvh写在后面,否则老浏览器连兜底都没有 - 搭配
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">才能确保 Safari 正确响应地址栏变化
示例写法:
section.fullscreen {<br> height: 100vh;<br> height: 100dvh;<br>}
Grid 场景下更稳妥的替代方案:用 min-height + flex 降级
如果项目需支持 iOS 15 或更低版本,或你发现 dvh 在某些 iPad Chrome 版本中仍不稳定,建议放弃纯 vh 单位,改用组合策略:
- 给 Grid 容器设
min-height: 100vh,而非height: 100vh,避免强制截断 - 用
display: flex+flex-direction: column替代 Grid 实现类似布局,对视口单位更宽容 - 关键:监听
window.innerHeight并同步更新 CSS 变量--vh,Grid 行高改用calc(var(--vh) * 1)
容易被忽略的一点:软键盘弹出时,resize 事件在 iOS 上不会触发,必须额外监听 focus/blur 事件来修正 --vh 值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











