h5移动端适配-dvh
📱 前端 H5 开发中合理使用 dvh
单位指南
在移动端 Web 开发中,使用 height: 100vh
经常会遇到布局被遮挡或跳动的问题。这通常是由于移动浏览器的地址栏和底部工具栏在滚动时会隐藏或显示,而 100vh
包含了这些工具栏区域,不是真正的可视区域。
为了解决这个问题,我们可以使用新的 CSS 单位 —— dvh
。
❓ 为什么 100vh
有问题?
- 移动浏览器(如 iOS Safari 或 Android Chrome)中,
100vh
包括地址栏和底部工具栏。 - 当用户滚动页面,地址栏隐藏时,页面高度会变化,导致:
- 页面布局跳动
- 内容被遮挡或超出可视区域
✅ 什么是 dvh
?
dvh
代表 Dynamic Viewport Height。1dvh = 当前可视区域高度的 1%
,会自动适应地址栏的显隐变化。- 是
vh
的现代替代方案。
示例:
.fullscreen {height: 100dvh;
}
✅ 优点
- 自动适应浏览器工具栏高度变化
- 无需额外 JS 监听或计算
- 在现代浏览器中工作良好
🔧 浏览器兼容性
浏览器 | 支持情况 |
---|---|
✅ Chrome 108+ | 支持 |
✅ Safari 15.4+ | 支持 |
✅ Edge 108+ | 支持 |
❌ Firefox | 尚未完整支持 |
❌ 旧安卓浏览器 | 不支持 |
📚 参考:Can I use dvh
🔙 回退方案(渐进增强)
为了更好的兼容性,可以采用以下写法:
.fullscreen {height: 100vh; /* 回退:旧浏览器使用 */height: 100dvh; /* 覆盖:现代浏览器使用 */
}
🧠 高级方案:使用 JS 设置变量兼容旧浏览器
若需兼容旧浏览器,可使用 JavaScript 设置 CSS 变量:
function setViewportHeight() {const vh = window.innerHeight * 0.01document.documentElement.style.setProperty('--vh', `${vh}px`)
}setViewportHeight()
window.addEventListener('resize', setViewportHeight)
配合 CSS 使用:
.fullscreen {height: calc(var(--vh, 1vh) * 100);
}
✅ 总结
方案 | 是否推荐 | 优势 | 劣势 |
---|---|---|---|
100vh | ❌ | 简单 | 不适配地址栏变化 |
dvh | ✅ | 自动适应,现代浏览器表现优秀 | 旧浏览器不支持 |
--vh + JS | ✅✅ | 高兼容,适配旧浏览器与现代浏览器 | 需写 JS,稍微复杂一些 |
📌 最佳实践建议
- 现代项目可直接使用
100dvh
- 兼容性要求高时,推荐使用
--vh
CSS 变量 + JS 动态计算
📂 示例代码封装(Vue 版本)
// useViewportHeight.ts
export function useViewportHeight() {const update = () => {const vh = window.innerHeight * 0.01document.documentElement.style.setProperty('--vh', `${vh}px`)}onMounted(update)onBeforeUnmount(() => window.removeEventListener('resize', update))onMounted(() => window.addEventListener('resize', update))
}
📚 延伸阅读
- Viewport units
- CSS Tricks on
dvh