Skip to content

fix(settings): 设置弹窗用 Portal 渲染避免被页面滚动条覆盖 (#580)#628

Merged
H-Chris233 merged 1 commit into
betafrom
fix/issue-580-settings-modal-portal
Jun 9, 2026
Merged

fix(settings): 设置弹窗用 Portal 渲染避免被页面滚动条覆盖 (#580)#628
H-Chris233 merged 1 commit into
betafrom
fix/issue-580-settings-modal-portal

Conversation

@appergb

@appergb appergb commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

User description

背景

issue #580:在历史记录页 / 风格页上下滑动后打开设置弹窗,页面的自定义滚动条(.ol-thinscroll)会覆盖在设置弹窗之上。报告者环境 Debian KDE Wayland(WebKitGTK),仅在滚动时出现。

根因

SettingsModal 遮罩层用 position: absolute; z-index: 50,但它和页面滚动条处在同一个 overflow: hidden 祖容器的 stacking context 内。WebKitGTK 下滚动条是元素自绘的一部分,不创建独立合成层,z-index 对其无效。issue 中已验证 position: fixed、主容器 isolation: isolate 均无效——因为问题不在 z-index 数值,而在于弹窗没有脱离那个 stacking context。

改动(仅 SettingsModal.tsx,单一职责)

  • createPortal 把弹窗渲染到 document.body,彻底脱离页面 DOM 树与 overflow:hidden 祖容器的 stacking context(与现有 SelectLite popover 同款做法)。
  • 遮罩层 positionabsolute 改为 fixed,覆盖整窗;视觉与交互(点遮罩关闭、毛玻璃背景、居中卡片动画)均不变。
  • 设计 token 定义在 :rootbody 下的 portal 正常继承,无样式丢失。

验证

  • npm run build(tsc + vite)✅
  • 平台验证:根因属 WebKitGTK 滚动条行为,建议在 Debian/KDE Wayland 上回归(reporter 环境);Portal 脱离 stacking context 是该类问题的标准解法。

注:MarketplaceModal 用了同款 backdrop 结构,理论上有相同隐患;为保持单一职责本 PR 未一并改动,可后续跟进。

🤖 Generated with Claude Code


PR Type

Bug fix


Description

  • 用 Portal 渲染设置弹窗,脱离 stacking context

  • 遮罩层改为 fixed 覆盖整窗

  • 修复 WebKitGTK 下滚动条覆盖问题


File Walkthrough

Relevant files
Bug fix
SettingsModal.tsx
设置弹窗使用 Portal 渲染                                                                                 

openless-all/app/src/components/SettingsModal.tsx

  • 导入 createPortal
  • 使用 createPortal 将弹窗渲染到 document.body
  • 遮罩层 positionabsolute 改为 fixed
  • 添加解释注释说明问题根因
+9/-3     

在历史/风格页滚动后打开设置弹窗,WebKitGTK(Debian/KDE Wayland)下页面自绘滚动条
(.ol-thinscroll) 会盖在弹窗之上。根因:弹窗用 position:absolute 处于页面 overflow:hidden
祖容器的同一 stacking context 内,而 WebKitGTK 滚动条不创建独立合成层,z-index 对其无效
(issue #580 中 position:fixed、isolation:isolate 均无效已验证)。

- SettingsModal 改用 createPortal 渲染到 document.body,彻底脱离页面 DOM 树与
  stacking context(与 SelectLite 的 popover 同款做法)。
- 遮罩层 position 由 absolute 改为 fixed,覆盖整窗;视觉与交互不变。
- 设计 token 定义在 :root,body 下的 portal 正常继承,无样式丢失。
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis 🔶

580 - Partially compliant

Compliant requirements:

  • 使用React Portal将SettingsModal渲染到document.body,完全脱离原有stacking context。
  • 遮罩层position改为fixed,覆盖整窗,视觉与交互不变。
  • 已通过npm run build验证。

Non-compliant requirements:

  • (无)

Requires further human verification:

  • 需要在Debian/KDE Wayland环境(WebKitGTK)回归测试,确保滚动条不再覆盖弹窗。
  • MarketplaceModal有相同隐患但未修改,可后续跟进。
⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ No major issues detected

@H-Chris233 H-Chris233 merged commit 7d37e4b into beta Jun 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants