Fix library tile buttons rendering above the sticky header while scrolling #18

Merged
kyuno merged 2 commits from fix/library-header-zindex into master 2026-09-16 22:41:28 +02:00
4 changed files with 56 additions and 2 deletions
Showing only changes of commit d23fcc028b - Show all commits

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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