From 6da98e476bace8cc495eeb2562684a924c4552a9 Mon Sep 17 00:00:00 2001 From: cucadmuh <49571317+cucadmuh@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:09:54 +0300 Subject: [PATCH] fix(ui): New badge flicker on mainstage album rail hover (#986) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(ui): stop New badge flicker on mainstage album rail first hover Dim cover via ::before under badges; keep play overlay transparent and avoid visibility toggles on rail action buttons. * docs: CHANGELOG for mainstage New badge hover fix (PR #986) * fix(ui): keep New badge above rail cover zoom (match grid stacking) Use contain:paint + translateZ layering like New Releases grid so scaled cover art does not paint over the badge during hover animation. * fix(ui): global album cover badge stacking for all rails and grids Move img/badge/overlay z-index into album-card.css; stop album-grid from resetting card transform or duplicating cover rules that hid New badges. * docs: CHANGELOG — badge stacking applies to all album rails * fix(ui): restore rail play buttons above scaled cover layer Raise play overlay and badge z-index on horizontal rails so WebKit does not paint zoomed cover art over hover controls after the New badge stacking fix. --- CHANGELOG.md | 6 ++++ src/styles/components/album-card.css | 2 ++ src/styles/components/album-row-container.css | 36 ++++++++++--------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64b01cbe..3b1654e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -563,6 +563,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **Album grids and song rails:** overlay `pointer-events` so the dim layer does not steal hover from the card. +### Mainstage album rails — stable New badge on first hover + +**By [@cucadmuh](https://github.com/cucadmuh), PR [#986](https://github.com/Psychotoxical/psysonic/pull/986)** + +* Horizontal album rails (Home New Releases, Discover, Favorites, Statistics, search rows, …) no longer hide the **New** / offline cover badges during hover zoom — cover stacking is shared with grid pages; rails keep dim-on-`::before` for play controls. + ### Album view — bulk add to playlist selection diff --git a/src/styles/components/album-card.css b/src/styles/components/album-card.css index 82096e31..7c123322 100644 --- a/src/styles/components/album-card.css +++ b/src/styles/components/album-card.css @@ -29,6 +29,8 @@ height: 100%; object-fit: cover; transform-origin: center center; + position: relative; + z-index: 0; transform: translateZ(0) scale(1); transition: opacity 0.15s ease, transform 350ms cubic-bezier(0.16, 1, 0.3, 1); } diff --git a/src/styles/components/album-row-container.css b/src/styles/components/album-row-container.css index aa3ff8d2..b04d93f7 100644 --- a/src/styles/components/album-row-container.css +++ b/src/styles/components/album-row-container.css @@ -107,7 +107,6 @@ no .card transition, hover pinned to cover, dim via overlay background not opacity. */ .album-grid .album-card { contain: none; - transform: none; transition: none; } @@ -115,42 +114,44 @@ box-shadow: inset 0 0 0 1px var(--border-subtle); } -.album-grid .album-card-cover { - contain: layout style; - transform: none; +/* Dim below badges/play controls (all horizontal rails: Home, Favorites, Statistics, …). */ +.album-grid .album-card-cover::before { + content: ''; + position: absolute; + inset: 0; + z-index: 1; + pointer-events: none; + background: transparent; } -.album-grid .album-card-cover img { - transform-origin: center center; - transform: scale(1); - transition: opacity 0.15s ease, transform 350ms cubic-bezier(0.16, 1, 0.3, 1); -} - -.album-grid .album-card-cover:hover img { - transform: scale(1.02); +.album-grid .album-card-cover:hover::before, +.album-grid .album-card-cover:focus-within::before { + background: rgba(0, 0, 0, 0.4); } .album-grid .album-card .album-card-play-overlay { + z-index: 4; + transform: translateZ(0); opacity: 1; background-color: transparent; transition: none; + pointer-events: none; } .album-grid .album-card .album-card-details-btn { - visibility: hidden; opacity: 0; + visibility: visible; pointer-events: none; transition: none; } .album-grid .album-card-cover:hover .album-card-play-overlay, .album-grid .album-card-cover:focus-within .album-card-play-overlay { - background-color: rgba(0, 0, 0, 0.4); + background-color: transparent; } .album-grid .album-card-cover:hover .album-card-details-btn, .album-grid .album-card-cover:focus-within .album-card-details-btn { - visibility: visible; opacity: 1; pointer-events: auto; } @@ -190,7 +191,8 @@ flex-direction: column; align-items: flex-end; gap: 4px; - z-index: 2; + z-index: 5; + transform: translateZ(0); pointer-events: none; } @@ -221,6 +223,8 @@ .album-card-play-overlay { position: absolute; inset: 0; + z-index: 2; + transform: translateZ(0); background: rgba(0, 0, 0, 0.4); display: flex; align-items: center;