真正靠谱的方案是用 min-height: 100dvh 并配好基础约束条件,因 100vh 在 ios safari 中为静态快照,不随地址栏、键盘显隐实时更新,而 100dvh 可动态响应,但需 @supports 降级兼容旧环境。

直接用 height: 100vh 实现移动端满屏高度,90% 的情况下会出问题——不是底部留白,就是滚动时内容跳动、输入框被键盘遮住。真正靠谱的方案是用 min-height: 100dvh,并配好基础约束条件。
为什么 100vh 在 iOS Safari 里总“不准”
它按页面加载瞬间的视口高度计算,而 iOS Safari 的地址栏和底部工具栏会随滚动收起/展开,window.innerHeight 实时变,但 100vh 不更新。结果就是:初始渲染时刚好,一滚动就错位——要么撑高出现滚动条,要么截断底部按钮。
-
100vh是“静态快照”,不是“实时高度” - 键盘弹出时,
100vh还按原来高度算,输入框直接被盖住 - 微信 WebView、QQ 浏览器等壳浏览器基本不修正这个行为,纯靠 CSS 无解
用 min-height: 100dvh 替代 height: 100vh
100dvh(dynamic viewport height)才是现代解法:它随地址栏、键盘显隐实时响应,iOS Safari 16.4+、Chrome 105+、Firefox 114+ 均已稳定支持。但不能直接写 height: 100dvh,否则内容超长会被裁剪、无法滚动。
- 必须用
min-height: 100dvh,保证至少一屏高,内容多时自然延展 - 搭配
html, body { margin: 0; padding: 0; },否则默认边距会吃掉高度 - 父容器需设
display: flex+justify-content: center+align-items: center才能真正居中——仅子元素设 flex 不生效
兼容旧浏览器必须加 @supports 降级
不是所有环境都认 100dvh。iOS 15 及更早、微信内置浏览器、部分安卓 WebView 会直接忽略该单位,导致高度塌陷。不能只写 fallback,得用 @supports 主动检测。
/* 兜底 */
.fullscreen {
min-height: 100vh;
}
/* 仅支持 dvh 的浏览器才覆盖 */
@supports (min-height: 100dvh) {
.fullscreen {
min-height: 100dvh;
}
}
- 别用
height: 100vh; height: 100dvh;这种层叠写法——旧浏览器解析到第一个就停,后面无效 -
svh和lvh不是通用替代品:100svh太保守(地址栏全显时高度),100lvh太激进(地址栏全隐时高度),场景有限 - 若项目必须跑在微信内,JS 动态注入
--vh变量仍是唯一稳解,监听resize而非scroll
容易被忽略的样式干扰点
即使写了 min-height: 100dvh,iOS 上仍可能高度不足或意外触发滚动条。问题常藏在这些细节里:
- 父级用了
position: fixed或position: absolute,脱离文档流后min-height失效 - 容器有
padding或border,但没设box-sizing: border-box,实际高度超出100dvh -
background-size: cover配合未设background-repeat: no-repeat,视觉上误判为高度不够 - 字体在 iOS 上因动态缩放变大,撑高内容,但
min-height不会自适应
真正麻烦的从来不是单位选哪个,而是 WebView 环境碎片化——dvh 再好,也救不了微信里那个不透出标准 API 的壳。动手前先查目标用户的真实运行环境,比堆 CSS 更重要。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











