React用vw/vh布局时滚动条出现页面错位怎么办?

伊果 阅读 44

我在做移动端页面时用了100vh设置容器高度,但页面出现滚动条后底部元素就被截断了,试过calc(100vh – env(safe-area-inset-bottom))也不管用,求大神指点

比如这个React组件:


const App = () => {
  return (
    <div className="page" style={{ height: '100vh' }}>
      <header style={{ height: '20%' }}>导航栏</header>
      <main style={{ height: '80%' }}>
        {/* 内容超出时会出现滚动条 */}
        {Array.from({length: 20}).map((_,i)=><div key={i}>内容{i}</div>)}
      </main>
    </div>
  );
};

当内容滚动到底部时,安卓手机会出现黑色条缝,iPhone X以上机型底部按钮区域也会被覆盖。用rem布局没问题,但需要适配不同屏幕比例时vw/vh明明更方便啊

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
雨帆 ☘︎
你这个问题其实挺常见的,根本原因就是 100vh 在移动端会被浏览器 UI 干扰。比如安卓的底部导航栏、iOS 的安全区,还有最关键的一点:100vh 是视口高度,但页面出现滚动条时,实际可用高度小于 100vh,所以内容会被截断。

直接用 100vh 做全屏容器在现代移动端是坑多的写法,可以优化成用 dvh(dynamic viewport height),这是专门解决滚动条和安全区动态变化的新单位。

把你的 style 改一下:

const App = () => {
return (

导航栏


{Array.from({ length: 20 }).map((_, i) =>
内容{i}
)}


);
};


100dvh 会自动适配动态环境,比如键盘弹出、安全区变化、滚动条占用空间等。现在主流安卓和 iOS 都支持了,兼容性够用。

如果非得兼容老版本,可以用 CSS 自定义属性降级:

.page {
height: calc(100vh - env(safe-area-inset-bottom));
height: 100dvh;
}


注意顺序,先写降级方案,再写 100dvh 覆盖,这样新设备用 dvh,旧设备至少还能靠 safe-area 补偿一点。

另外提醒一句,别在 body 或根元素上设 overflow: hidden 去强行隐藏滚动条,那只会让问题更隐蔽。让滚动正常发生,用正确的视口单位才是正解。
点赞 5
2026-02-12 23:15