From d23fcc028bc00f767bc549b4e2a041792155f394 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 16 Sep 2026 22:37:11 +0200 Subject: [PATCH] Fix library tile buttons rendering above the sticky header while scrolling .libraryHeader and the alphabet index's .letterHeading copied their z-index: 2 from tiles.css's own pre-existing sticky .searchBar - which never showed the problem in practice, since a single slim input has little room to actually overlap a scrolling tile. A tile's own .tileOverlay action buttons are also z-index: 2 though, and an equal z-index ties toward whichever renders later in the DOM - a tile, always after the header. Wrapping the header into a much taller block gave a scrolling tile far more room to pass underneath before fully clearing it, which is what actually surfaced the tie. Raised both to z-index: 3, matching shell/Shell.css's own mobileTopBar. Co-Authored-By: Claude Sonnet 5 --- README.md | 3 +++ client/src/alphaIndex.css | 6 ++++- client/src/views/library/Library.css | 13 +++++++++- docs/architecture.md | 36 ++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 30be34b..96c5182 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,9 @@ Then put it behind your existing reverse proxy like everything else it was bucketing by display name instead of Emby's own SortName, so an article-stripped title ("The ...") threw a whole run off — see docs/architecture.md +- [x] Fixed library tile buttons rendering on top of the sticky header + while scrolling — an equal z-index tie that a scrolling tile won + — see docs/architecture.md - [ ] Try a full party end-to-end with two real accounts (still the main gap) - [ ] Try casting to a real Chromecast (only the SDK's own bootstrap is confirmed here — no real device/session) diff --git a/client/src/alphaIndex.css b/client/src/alphaIndex.css index bfae618..3923e39 100644 --- a/client/src/alphaIndex.css +++ b/client/src/alphaIndex.css @@ -8,7 +8,11 @@ grid-column: 1 / -1; position: sticky; top: var(--section-sticky-top, 0px); - z-index: 2; + /* Same z-index: 3 as views/library/Library.css's own .libraryHeader, + and for the identical reason: tiles.css's .tileOverlay is z-index: + 2, and a tie there breaks toward whichever renders later in the + DOM - a tile, always after this heading. */ + z-index: 3; background: var(--bg); color: var(--accent-bright); font-size: 13px; diff --git a/client/src/views/library/Library.css b/client/src/views/library/Library.css index 71cc115..167d976 100644 --- a/client/src/views/library/Library.css +++ b/client/src/views/library/Library.css @@ -8,7 +8,18 @@ .libraryHeader { position: sticky; top: 0; - z-index: 2; + /* Above 2, not just tiles.css's own .searchBar precedent: a tile's + .tileOverlay action buttons are ALSO z-index: 2, and (unlike the + slim .searchBar this header replaced) this header is tall enough + that a scrolling tile's own overlay - always-visible on touch, see + tiles.css's (hover: none) block - reaches it well before it's fully + scrolled past. Equal z-index ties break on paint order, and a tile + (inside #grid, after this header in the DOM) wins that tie - + reported directly as buttons rendering over the header while + scrolling. z-index: 3 matches shell/Shell.css's own .mobileTopBar, + the other sticky header this one already has to stack correctly + under on mobile. */ + z-index: 3; background: var(--bg); padding-top: 4px; } diff --git a/docs/architecture.md b/docs/architecture.md index 616f5ef..cd10c20 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -4103,6 +4103,42 @@ it produced the same `A, B, T, B, L` heading sequence against the old bucket-by-`name` code, then confirmed the fix collapses it to the correct `A, B, L` against the exact same input. +## Library tile buttons rendering on top of the sticky header + +Reported directly: scrolling a library, a tile's own action buttons +("Lancer une watch party" / "Voir sur Emby") would briefly render +*above* the sticky title+search header instead of scrolling behind it. + +Both `.libraryHeader` and the alphabet index's `.letterHeading` were +`z-index: 2` - copied from `tiles.css`'s own pre-existing `.searchBar`, +sticky at that same value long before either of them existed. What +that copy missed: a tile's own `.tileOverlay` (its hover-revealed +action buttons - always-visible rather than hover-revealed on a touch +device, see `tiles.css`'s `(hover: none)` block) is *also* `z-index: 2`. +Equal z-index is a tie, and a tie breaks toward whichever renders later +in the DOM - a tile, inside `#grid`, always after the header. The +original slim `.searchBar` never showed this in practice (a single +input has little vertical range to actually overlap a scrolling tile +during the transition); wrapping it into the much taller +`.libraryHeader` gave a scrolling tile far more room to pass directly +underneath before fully clearing it, is what actually surfaced it. + +Fixed by raising `.libraryHeader` and `.letterHeading` to `z-index: 3` +- comfortably clear of `.tileOverlay`'s 2, and matching +`shell/Shell.css`'s own `.mobileTopBar` (the other sticky header +`.libraryHeader` already has to stack correctly under on mobile). + +Verified: full `typecheck`/`build` (client only). Confirmed as a real +regression, not just reasoned about - real compiled CSS loaded into a +page reproducing `.libraryHeader` + a real `.grid` of tiles (their +`.tileOverlay` forced visible, simulating a touch device), scrolled so +a tile genuinely overlapped the header's own rect, then +`elementsFromPoint` read the actual paint order at that point: with +the header's z-index forced back to the old `2`, `.tileOverlay` topped +the stack exactly as reported; restored to `3`, the header (and the +search input inside it) topped it instead, `.tileOverlay` three layers +down, unreachable. + ## Known limitations - Playback always goes through `hls.js` against whatever Emby's