2.5 KiB
2.5 KiB
滚动条覆盖底部导航栏 - 原因分析与解决方案
已解决:将滚动从 viewport 移至
app-main-scroll内部,滚动条不再覆盖底部导航。
现象
底部导航栏(v-bottom-navigation)被页面滚动条遮挡,即使设置 z-index: 1100 和 transform: translateZ(0) 仍无法解决。
根本原因
1. 滚动发生在 viewport(body/html)
当前布局中,页面滚动发生在 文档根 上:
Home.vue使用window.scrollY、document.documentElement.scrollHeight监听滚动router/index.ts的scrollBehavior返回{ top: 0 },作用于window.home-list-scroll未设置overflow,内容随 窗口 滚动
因此,滚动条属于 viewport,由浏览器在 html/body 上绘制。
2. 原生 viewport 滚动条不受 z-index 控制
- 滚动条是浏览器原生 UI,不是普通 DOM 元素
- 它由浏览器在单独图层渲染,与文档层叠上下文分离
- 不同浏览器行为不同:
- Chrome:fixed 元素有时能盖住滚动条
- Firefox / Edge:滚动条通常绘制在 fixed 元素之上
- 对这类原生滚动条,z-index 无法可靠控制其与 fixed 元素的层级
3. 当前 DOM 结构
v-app
├── v-app-bar (fixed top)
├── v-main (flex: 1,内容区)
│ └── main-content → router-view → Home/Search/Profile
└── v-bottom-navigation (fixed bottom)
- 底部导航是
v-app的子节点,position: fixed - 滚动发生在 body,滚动条在 viewport 右侧贯穿全屏
- 底部导航与滚动条在视觉上重叠,且无法通过 z-index 调整
解决方案(已实现)
核心思路:把滚动从 viewport 移到 内部滚动容器 app-main-scroll,让滚动条只出现在内容区,不延伸到底部导航区域。
实现要点
- App.vue:
html, body与.v-application设置overflow: hidden;v-main 内新增app-main-scroll(data-main-scroll)作为滚动容器,overflow-y: auto - router:
scrollBehavior改为滚动[data-main-scroll]元素 - Home.vue:
checkScrollLoad使用 scroll 容器的scrollTop/scrollHeight/clientHeight;IntersectionObserver的 root 改为 scroll 容器;监听 scroll 容器的scroll事件 - Search.vue:
IntersectionObserver的 root 改为 scroll 容器
效果:滚动条仅出现在 app-main-scroll 内,底部导航栏固定于 viewport 底部,不再被滚动条覆盖。