xtraderClient/docs/scrollbar-nav-overlap.md
2026-03-20 19:01:14 +08:00

2.5 KiB
Raw Blame History

滚动条覆盖底部导航栏 - 原因分析与解决方案

已解决:将滚动从 viewport 移至 app-main-scroll 内部,滚动条不再覆盖底部导航。

现象

底部导航栏v-bottom-navigation被页面滚动条遮挡即使设置 z-index: 1100transform: translateZ(0) 仍无法解决。

根本原因

1. 滚动发生在 viewportbody/html

当前布局中,页面滚动发生在 文档根 上:

  • Home.vue 使用 window.scrollYdocument.documentElement.scrollHeight 监听滚动
  • router/index.tsscrollBehavior 返回 { top: 0 },作用于 window
  • .home-list-scroll 未设置 overflow,内容随 窗口 滚动

因此,滚动条属于 viewport,由浏览器在 html/body 上绘制。

2. 原生 viewport 滚动条不受 z-index 控制

  • 滚动条是浏览器原生 UI不是普通 DOM 元素
  • 它由浏览器在单独图层渲染,与文档层叠上下文分离
  • 不同浏览器行为不同:
    • Chromefixed 元素有时能盖住滚动条
    • 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,让滚动条只出现在内容区,不延伸到底部导航区域。

实现要点

  1. App.vuehtml, body.v-application 设置 overflow: hiddenv-main 内新增 app-main-scrolldata-main-scroll)作为滚动容器,overflow-y: auto
  2. routerscrollBehavior 改为滚动 [data-main-scroll] 元素
  3. Home.vuecheckScrollLoad 使用 scroll 容器的 scrollTop/scrollHeight/clientHeightIntersectionObserver 的 root 改为 scroll 容器;监听 scroll 容器的 scroll 事件
  4. Search.vueIntersectionObserver 的 root 改为 scroll 容器

效果:滚动条仅出现在 app-main-scroll 内,底部导航栏固定于 viewport 底部,不再被滚动条覆盖。