vw/vh在移动端适配时为什么有时候失效?
我用 vw 做了一个全屏的卡片组件,但在某些安卓机上高度明显不对,vh 好像没生效。试过加 meta viewport 了,还是不行。
这是我的 Vue 组件代码:
<template>
<div class="full-screen-card">
<h2>欢迎</h2>
</div>
</template>
<style scoped>
.full-screen-card {
width: 100vw;
height: 100vh;
background: #f0f0f0;
}
</style>
在 iPhone 上显示正常,但在一些老款安卓机(比如华为 P20)上,底部会被导航栏挡住,实际高度比屏幕小。是不是 vh 在有虚拟导航栏的设备上有坑?该怎么解决?
根本原因是:vh 的计算方式在移动端浏览器里不太靠谱。当地址栏显示或隐藏时,浏览器会重新计算视口高度,导致你的 100vh 跟着变。而且安卓机的底部虚拟导航栏(就是三大金刚键或者全面屏手势那条线)也会影响视口,但浏览器不会把这个高度差暴露给你。
iOS Safari 聪明一点,它把 vh 设成了一个固定值,所以通常没问题。但安卓浏览器会实时响应地址栏状态,vh 就飘了。
解决办法:
CSS 的话,用
dvh或svh替代vh。dvh 是动态视口高度,会随浏览器 UI 变化;svh 是小型视口高度,取的是浏览器 UI 展开时的最小高度。如果还要兼容更老的浏览器(不支持 dvh/svh),可以这样写:
或者直接用
position: fixed配合top: 0; bottom: 0,这个方案兼容性最好:这样写的好处是完全不依赖 vh/dvh,甭管浏览器 UI 怎么变,它都能撑满整个屏幕。
老款安卓机(尤其是华为)浏览器内核比较老,建议直接用 position: fixed 方案,一劳永逸。