Fixed positioning escaped the clipping, but not the stacking.
.tab-bar carries z-index: 2, which makes it a stacking context — so any z-index a descendant carries is confined below level 2, no matter how large. The spectrum overlays paint as high as 9600, so both dropdowns opened underneath them. Raising the menu's own z-index cannot fix this; the number is meaningless outside its context.
The fix
Reparent each menu to document.body when it opens. Leaving that subtree is the only way out of an ancestor's stacking context. The menus are already positioned in viewport coordinates, so nothing else about them changes.
The outside-click test now considers the menu as well as its wrapper, since the two are no longer nested — without that, clicking an item would dismiss the menu before the click registered.
Verified by hit testing
Not by inspecting z-index, which is what made the previous attempt look correct:
## Why the previous fix wasn't enough
Fixed positioning escaped the *clipping*, but not the *stacking*.
`.tab-bar` carries `z-index: 2`, which makes it a stacking context — so any z-index a descendant carries is confined below level 2, no matter how large. The spectrum overlays paint as high as **9600**, so both dropdowns opened underneath them. Raising the menu's own z-index cannot fix this; the number is meaningless outside its context.
## The fix
Reparent each menu to `document.body` when it opens. Leaving that subtree is the only way out of an ancestor's stacking context. The menus are already positioned in viewport coordinates, so nothing else about them changes.
The outside-click test now considers the menu as well as its wrapper, since the two are no longer nested — without that, clicking an item would dismiss the menu before the click registered.
## Verified by hit testing
Not by inspecting z-index, which is what made the previous attempt look correct:
```
parent: BODY zIndex: 9700 rect: 206×193
elementFromPoint(menu centre) -> mobile-more-menu insideMenu: true
```
The menu is the topmost painted element at its own centre. Screenshot confirms it drawing over the spectrum panel.
Full gate green — `typecheck`, `lint`, 34/34 `test`, `build`, `test:browser`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01GdyUjuXejCEfiub675z6cz
Fixed positioning escaped the clipping, but not the stacking: the header
carries `z-index: 2`, which makes it a stacking context, so whatever
z-index a menu inside it carries is confined below level 2. The spectrum
overlays paint as high as 9600, so both dropdowns opened underneath them.
Reparent each menu to the body when it opens. Leaving that subtree is
the only way out of an ancestor's stacking context, and the menus are
already positioned in viewport coordinates, so nothing else about them
changes. The outside-click test now considers the menu as well as its
wrapper, since the two are no longer nested.
Verified by hit testing rather than by inspecting z-index:
elementFromPoint at the open menu's centre returns the menu.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GdyUjuXejCEfiub675z6cz
Signed-off-by: Stan Grams <sjg@haxx.space>
sjg
merged commit b06c37affa into main2026-08-02 23:31:19 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why the previous fix wasn't enough
Fixed positioning escaped the clipping, but not the stacking.
.tab-barcarriesz-index: 2, which makes it a stacking context — so any z-index a descendant carries is confined below level 2, no matter how large. The spectrum overlays paint as high as 9600, so both dropdowns opened underneath them. Raising the menu's own z-index cannot fix this; the number is meaningless outside its context.The fix
Reparent each menu to
document.bodywhen it opens. Leaving that subtree is the only way out of an ancestor's stacking context. The menus are already positioned in viewport coordinates, so nothing else about them changes.The outside-click test now considers the menu as well as its wrapper, since the two are no longer nested — without that, clicking an item would dismiss the menu before the click registered.
Verified by hit testing
Not by inspecting z-index, which is what made the previous attempt look correct:
The menu is the topmost painted element at its own centre. Screenshot confirms it drawing over the spectrum panel.
Full gate green —
typecheck,lint, 34/34test,build,test:browser.🤖 Generated with Claude Code
https://claude.ai/code/session_01GdyUjuXejCEfiub675z6cz