移动端表格滚动的双重滚动问题
在移动端调试表格组件时,会出现"双重滚动"的bug:滚动到底部后需要松手再滚动才能继续,滚动到顶部同样需要停顿。这是因为中间内容区域和外层容器各有一个独立的滚动区域。
问题根因
移动端屏幕高度与浏览器可视窗口高度不一致。屏幕获取的是从顶部到底部的整个高度(包含状态栏、底部导航栏等),而实际可用区域需要减去安全区域(Safe Area)。
Safe Area安全区域
Safe Area是移动端特有的概念,指的是屏幕上除去状态栏、底部导航栏等系统UI后的可用区域。
兼容性
env(safe-area-inset-*) 在 Can I Use 上显示,除IE外所有主流浏览器均支持。
UnoCSS中的Safe Area配置
UnoCSS中的写法需要使用CSS原生写法(不支持驼峰),在 uno.config.ts 中配置:
// uno.config.ts
export default defineConfig({
shortcuts: {
'm-safe': 'pt-[env(safe-area-inset-top)] pb-[env(safe-area-inset-bottom)]'
}
})
typescript
在布局组件最外层添加 m-safe 类名即可。
viewport设置
移动端还需要在 index.html 中正确设置viewport:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
html
最终解决方案:放弃h-screen
经过真机调试发现,仅设置safe-area并不能完全解决问题。最终方案是放弃 h-screen,改用百分比高度配合定位:
/* 最外层容器 */
.layout-wrapper {
height: 100%;
position: fixed;
left: 0;
top: 0;
overflow: hidden;
}
/* 右侧内容区域 */
.content {
flex: 1;
overflow-y: auto;
height: 100%;
width: 100%;
}
css
核心原则:不要自定义移动端的滚动行为。让浏览器控制滚动(地址栏折叠、弹性回弹等),用户的感知与其他网页一致。自定义滚动条会导致卡顿、行为不一致等问题,尤其在设备碎片化的移动端,维护成本极高。
PC端兼容
改造后PC端需要确保内容区域宽度正确:
.content {
flex: 1;
overflow: hidden; /* 防止折叠菜单时宽度异常 */
}
css
↑