Skip to content

fix(ui): 修复搜索栏盖住顶栏与弹层背景可滚动两个问题 - #312

Merged
AmintaCCCP merged 1 commit into
mainfrom
fix/header-layering-modal-scroll-lock
Aug 29, 2026
Merged

fix(ui): 修复搜索栏盖住顶栏与弹层背景可滚动两个问题#312
AmintaCCCP merged 1 commit into
mainfrom
fix/header-layering-modal-scroll-lock

Conversation

@AmintaCCCP

@AmintaCCCP AmintaCCCP commented Aug 29, 2026

Copy link
Copy Markdown
Owner

问题

  1. 仓库页 AI 搜索栏滚动到顶栏位置时会盖住顶栏

    • 根因:Headersticky top-0 z-40,而 SearchBar 输入行为 relative z-40。两者同一层叠级别(z-40),搜索栏在 DOM 中靠后,同层级后者胜出,因此页面滚动使搜索栏进入顶栏区域时直接绘制在顶栏之上。
    • 修复:顶栏提升到 z-50。顶栏属于页面 chrome,应始终高于文档流内容;Radix portal 弹层(z-50、挂在 body 末尾)仍按文档顺序盖在顶栏之上,层叠关系不受影响。
  2. 仓库问答边栏出现两个滚动条,最右侧滚动条在边栏弹出时仍能滚动遮罩下层的仓库列表

    • 根因:Radix Dialog 的 react-remove-scroll 只把 overflow 写在 body 上;但本应用视口滚动条属于 htmloverflow-y: scroll),body 的 overflow 不会传播到视口,所以遮罩下层的页面依旧可以被滚动(滚动条拖拽 + 滚轮)。边栏内消息列表自带一条滚动条,加上仍然可用的视口滚动条,视觉上就是“两个滚动条”。
    • 修复:index.css 增加 html:has(body[data-scroll-locked]) { overflow: hidden !important; },在任意 Radix 模态打开期间直接锁住真正的根滚动容器。选用 hidden 而非 clip:hidden 下视口仍是 scroll container,滚动偏移、position: sticky 顶栏锚点与 scrollbar-gutter: stable 预留槽位在锁定期间全部保持不变,关闭后原位恢复。原有 body[data-scroll-locked] { overflow: clip } 规则保留(继续压制库内联写入的 body overflow,避免 body 变成 scroll container 导致 sticky 失锚)。

验证

  • Playwright E2E(dev server + mock GitHub API,含登录态注入):12/12 断言通过
    • 页面滚动使搜索栏与顶栏重叠时,elementFromPoint 命中 header 而非搜索框;header z-index 为 50
    • 打开仓库问答:data-scroll-locked 生效、html overflow 为 hidden、滚动偏移保持、锁定前后 clientWidth 不变(无布局抖动)、在遮罩上滚轮无法滚动背景
    • 关闭后:锁定解除、overflow 恢复 scroll、偏移保持、页面可继续滚动
  • 有头 Chromium 受控实验确认:overflow: hiddenscrollbar-gutter: stable 的槽位不会塌陷,无需额外补偿
  • npm run typecheckeslintvitest(65 个文件 / 588 个用例)全部通过

Summary by CodeRabbit

  • Bug 修复

    • 修复弹窗或覆盖层打开时页面仍可通过滚轮或滚动条继续滚动的问题。
    • 保留页面滚动位置、吸顶元素定位及滚动条占位,改善弹窗交互体验。
  • 样式

    • 提升页面顶部导航层级,确保其显示在其他内容和覆盖层之上。

… sheets

- Header sticky top bar raised z-40 -> z-50. The repository search bar's
  input row sits at relative z-40 later in the DOM, so once it scrolled up
  to the header band it painted on top of the header (same stacking level,
  later order wins). The header is page chrome and must sit above in-flow
  page content; Radix portals keep stacking above it via document order.
- Modal scroll lock now reaches the root scroller. react-remove-scroll
  only writes overflow on body, but body overflow never propagates to the
  viewport because html owns overflow (overflow-y: scroll), so the page
  behind the RepositoryChatSheet overlay stayed scrollable (scrollbar
  drag + wheel) — the "second scrollbar" next to the sheet's message list.
  html:has(body[data-scroll-locked]) { overflow: hidden } locks the real
  scroller; hidden (not clip) keeps the viewport a scroll container so the
  scroll offset, the sticky header anchor and the scrollbar-gutter
  reservation all survive the lock, and the lock releases on close.

Verified with a Playwright E2E against the dev server (mocked GitHub API):
12/12 checks — header paints above the search bar at overlap, sheet open
freezes page scroll (wheel + offset preserved), unlock restores scrolling.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b1d8dad5-af5e-4793-9949-cfa8a89a3305

📥 Commits

Reviewing files that changed from the base of the PR and between 95ea52e and 7a938b7.

📒 Files selected for processing (2)
  • src/components/Header.tsx
  • src/index.css

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

本次变更调整页头的层级,并新增根滚动容器锁定规则。滚动锁定时,html 使用 overflow: hidden !important

Changes

界面覆盖层行为

Layer / File(s) Summary
页头层级调整
src/components/Header.tsx
<header> 元素的 z-indexz-40 调整为 z-50
根滚动容器锁定
src/index.css
body 带有 data-scroll-locked 属性时,为 html 设置 overflow: hidden !important。规则保留滚动偏移、sticky 锚点和 scrollbar-gutter: stable 的行为。

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 7a938

该 PR 仅调整顶栏层级并在弹层打开时锁定页面背景滚动,影响范围局限于浏览器界面行为;当前没有可操作的合并阻断风险,完成常规检查后即可合并。

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了两个主要变更:修复搜索栏遮挡顶栏,以及修复弹层打开时背景页面仍可滚动的问题。标题简洁且与变更内容一致。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AmintaCCCP
AmintaCCCP merged commit c2f74dc into main Aug 29, 2026
9 checks passed
@AmintaCCCP
AmintaCCCP deleted the fix/header-layering-modal-scroll-lock branch August 29, 2026 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant