vw/vh在移动端适配时为什么有时候失效?

长孙秀云 阅读 98

我用 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 在有虚拟导航栏的设备上有坑?该怎么解决?

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
Code°瑞娜
这个问题挺常见的,vh 在移动端尤其是安卓机上确实有坑。

根本原因是:vh 的计算方式在移动端浏览器里不太靠谱。当地址栏显示或隐藏时,浏览器会重新计算视口高度,导致你的 100vh 跟着变。而且安卓机的底部虚拟导航栏(就是三大金刚键或者全面屏手势那条线)也会影响视口,但浏览器不会把这个高度差暴露给你。

iOS Safari 聪明一点,它把 vh 设成了一个固定值,所以通常没问题。但安卓浏览器会实时响应地址栏状态,vh 就飘了。

解决办法:

CSS 的话,用 dvhsvh 替代 vh。dvh 是动态视口高度,会随浏览器 UI 变化;svh 是小型视口高度,取的是浏览器 UI 展开时的最小高度。

.full-screen-card {
width: 100vw;
height: 100dvh; /* 或者用 100svh */
background: #f0f0f0;
}


如果还要兼容更老的浏览器(不支持 dvh/svh),可以这样写:

.full-screen-card {
width: 100vw;
height: 100vh;
height: 100dvh;
height: 100svh;
height: -webkit-fill-available; /* 兜底 */
}


或者直接用 position: fixed 配合 top: 0; bottom: 0,这个方案兼容性最好:

.full-screen-card {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #f0f0f0;
}


这样写的好处是完全不依赖 vh/dvh,甭管浏览器 UI 怎么变,它都能撑满整个屏幕。

老款安卓机(尤其是华为)浏览器内核比较老,建议直接用 position: fixed 方案,一劳永逸。
点赞
2026-03-18 01:00