100vh在移动端“短一截”是因浏览器按含地址栏的初始视口静态计算高度,滚动后地址栏收起但值不更新,导致背景裁切、露白边;安卓webview还可能按物理屏高计算,误差更大。

直接原因不是 Flex 本身,而是 100vh 在移动端的计算偏差叠加了 Flex 容器的默认行为。你设了 height: 100vh,但浏览器实际给的高度可能比用户此刻能看到的区域高(比如 iOS Safari 按地址栏收起状态算),而 Flex 子项又没被约束收缩或溢出处理,结果内容“撑破”容器,触发滚动条。
为什么 overflow: hidden 在 flex + 100vh 下经常失效
overflow: hidden 只管当前元素内部内容是否裁剪,但它不解决父级尺寸错位问题。常见失效场景包括:
-
html或body有默认margin(通常是8px),哪怕只多这 4px,总高度就 >100vh - Flex 容器设了
height: 100vh,但子项用了min-height: 100vh或height: 100%,形成双重叠加 - 子项带
padding或border,且box-sizing是默认的content-box,导致总高超出 - Flex 容器未设
overflow,子项溢出后“推高”整个容器,滚动条出现在body层级而非容器自身
Flex 容器内内容溢出却不滚动?关键在 flex-shrink 和 overflow 同时配置
很多人加了 overflow-y: auto 却没滚动条,是因为 Flex 默认允许子项收缩(flex-shrink: 1),内容被压缩到“不溢出”,自然不触发滚动。必须同时满足:
- Flex 容器设
overflow-y: auto(纵向)或overflow-x: auto(横向) - 子项显式设
flex-shrink: 0(禁用收缩) - 容器有明确高度限制(如
height: 100vh或max-height: calc(100vh - 60px)) - 若子项含文字,加
white-space: nowrap防止内部折行干扰溢出判断
用 100dvh 替代 100vh 是最简修复,但要注意声明顺序和兜底
100dvh(dynamic viewport height)是专为动态视口设计的单位,iOS Safari 16.4+、Chrome 105+、Firefox 112+ 均支持。它能真实反映地址栏可见/隐藏时的当前可视高度。
- 必须把
height: 100vh写在前,height: 100dvh写在后,否则老浏览器连回退都没有 - 搭配
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">才能确保 Safari 正确响应地址栏变化 - 如果项目需兼容 iOS 15 或更低版本,建议改用
min-height: 100vh+overflow: hidden组合,或监听window.innerHeight动态更新 CSS 变量--vh
真正容易被忽略的点是:滚动条往往不在你写的那个 Flex 容器上,而在 body 或 html 上;所以排查时先检查 html, body { margin: 0; height: 100%; } 是否齐全,再看容器自身的 box-sizing 和子项的 flex-shrink 状态。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











