-webkit-fill-available 不是解药,因其在移动端对 height 支持不稳定、不响应地址栏动态变化且 Chrome 完全不识别;100dvh 才是语义正确、主流浏览器已支持的实时可见高度单位。

直接用 -webkit-fill-available 不能解决 100vh 包含工具栏的问题——它和 100vh 一样,计算依据仍是包含地址栏的“布局视口(layout viewport)”,不是用户实际看到的区域。
为什么 -webkit-fill-available 不是解药
这个值常被误传为“撑满可见区域”的万能方案,但它在移动端的实际行为是:
-
-webkit-fill-available是 WebKit 早期为表单控件(如input)设计的内部填充逻辑,不适用于通用容器高度设置 - 在 iOS Safari 中,它对
height属性的支持不稳定;部分版本下会退化为auto或触发意外重排 - 它无法响应地址栏收起/展开的动态变化,和
100vh一样“冻结”在初始值 - Chrome / Android WebView 完全不识别该值用于
height,会直接忽略
100dvh 才是语义正确的替代方案
如果你的目标是“始终等于当前可见屏幕高度”,100dvh 是唯一符合规范、有明确语义且已被主流浏览器实现的单位。
- Chrome 105+、Safari 16.4+、Firefox 112+ 均已支持,覆盖 2023 年后绝大多数活跃设备
- 它由浏览器原生更新,无需 JS 干预,无节流/防抖负担,也不存在
getComputedStyle读不到数值的问题 - 写法极简:
height: 100vh; height: 100dvh;—— 后声明者生效,老浏览器自动 fallback - 注意:不能用于
@media查询条件(如@media (min-height: 100dvh)无效),这点和vh一致
必须兼容 iOS 15 及更早版本?用 --vh + resize 节流
当项目明确要求支持 iOS 15 或微信内置浏览器(基于旧版 WKWebView)时,JS 动态方案仍是必要兜底。
- 首次执行必须在
DOMContentLoaded前或立即同步运行,否则白屏阶段高度就错 -
resize事件在 iOS 上滚动时高频触发,直接赋值style.height会导致强制同步布局,卡顿明显;务必用requestAnimationFrame包裹更新逻辑 - 只更新真正需要适配的元素,比如加了
data-dynamic-height的容器,避免全局重排 - CSS 中写
height: calc(var(--vh, 1px) * 100),别漏掉单位(1px而非1vh),否则 fallback 会失效
svh / lvh 是补充,不是替代
这三个新单位(svh、lvh、dvh)是并列关系,各自适用不同场景:
-
100svh= 工具栏完全显示时的高度 → 适合底部固定按钮、输入框等“必须始终可见”的元素 -
100lvh= 工具栏完全隐藏时的高度 → 适合全屏视频、启动页等“最大化沉浸”的场景 -
100dvh= 当前实时可见高度 → 就是你想要的“真正 100vh” - 三者都不能用于
@media,也不能在 JS 中通过getComputedStyle读取为像素值(返回字符串如"100dvh")
复杂点在于:你得先判断自己要的是“始终可见”“最大沉浸”还是“实时匹配”——选错单位,比用回 100vh 还容易出视觉 bug。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











