React用vw/vh布局时滚动条出现页面错位怎么办?
我在做移动端页面时用了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明明更方便啊
100vh在移动端会被浏览器 UI 干扰。比如安卓的底部导航栏、iOS 的安全区,还有最关键的一点:100vh是视口高度,但页面出现滚动条时,实际可用高度小于100vh,所以内容会被截断。直接用
100vh做全屏容器在现代移动端是坑多的写法,可以优化成用dvh(dynamic viewport height),这是专门解决滚动条和安全区动态变化的新单位。把你的 style 改一下:
100dvh会自动适配动态环境,比如键盘弹出、安全区变化、滚动条占用空间等。现在主流安卓和 iOS 都支持了,兼容性够用。如果非得兼容老版本,可以用 CSS 自定义属性降级:
注意顺序,先写降级方案,再写
100dvh覆盖,这样新设备用 dvh,旧设备至少还能靠 safe-area 补偿一点。另外提醒一句,别在
body或根元素上设overflow: hidden去强行隐藏滚动条,那只会让问题更隐蔽。让滚动正常发生,用正确的视口单位才是正解。