100vh 在移动端不可靠,因其为静态值,不随地址栏、键盘显隐实时更新,导致滚动错位或输入框被遮挡;应优先用 min-height: 100dvh 并 @supports 降级至 100vh,必要时辅以 JS 动态同步 --vh。

直接用 100vh 做高度基准,在 iOS Safari 或微信 WebView 里基本会错位——地址栏收起时内容被顶出视口,弹出键盘时输入框直接被盖住。
为什么 100vh 在移动端不可靠
100vh 是页面加载瞬间计算的静态值,不随地址栏、工具栏、虚拟键盘的显隐实时更新。iOS Safari 的 window.innerHeight 滚动时会变,但 100vh 不会跟着变。
- 初始渲染正常,一滚动就底部留白或内容截断
- 聚焦
弹出键盘后,100vh还按全高算,输入框被遮挡 - 微信、QQ 浏览器等壳浏览器几乎不修正该行为,纯 CSS 无解
用 100dvh 替代并加降级逻辑
100dvh(dynamic viewport height)是真正响应式单位,iOS Safari 16.4+、Chrome 105+、Firefox 114+ 已稳定支持,它随地址栏/键盘实时更新。
- 必须用
min-height: 100dvh,不能用height: 100dvh,否则内容超长会被裁剪 - 用
@supports降级:不支持dvh的旧环境 fallback 到100vh - CSS 示例:
html, body {
margin: 0;
}
body {
min-height: 100dvh;
}
@supports not (min-height: 100dvh) {
body {
min-height: 100vh;
}
}
兼容极老环境的 JS 补丁方案
若需支持 iOS 15.6 以下或 Android 4.4 WebView,得手动同步视口高度:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 监听
resize,节流后更新 CSS 自定义属性--vh - CSS 中用
calc(100vh * var(--vh))计算动态高度(注意不是乘法,是单位换算) - 必须在 DOM 加载完立即执行一次
updateVh(),否则首屏白屏或错位
底栏、弹窗等关键组件要额外约束
即使用了 100dvh,底栏仍可能因 fixed 定位受虚拟键盘挤压跳动:
- 外层容器用
position: fixed; bottom: 0; width: 100vw(不是100%) - 按钮组内层用
display: grid控制双列,禁用flex直接排布 - 设
min-width: 88px和min-height: 44px保触控区,防 iOS 自动缩放破坏布局 - 务必移除
user-scalable=yes,否则双击放大后底栏错位无法恢复
真正麻烦的不是写对 100dvh,而是所有依赖视口高度的组件(底栏、弹窗、全屏图、表单容器)都得同步适配;漏掉一个,整屏体验就崩。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










