fix(ui): stable play/enqueue hover on album rails and mainstage cards (#787)

* fix(ui): stable play/enqueue hover on album rails and mainstage cards

Horizontal Home rails (Discover): drop content-visibility:auto and scroll-snap,
pin controls to cover hover, dim overlay via background. Grids and song cards:
pointer-events on overlays so WebKitGTK/Wayland GPU does not lose :hover.

* chore: CHANGELOG and credits for PR #787
This commit is contained in:
cucadmuh
2026-05-18 23:35:08 +03:00
committed by GitHub
parent d7abf9be3b
commit d7b23b3c08
5 changed files with 91 additions and 12 deletions
+64 -9
View File
@@ -52,7 +52,7 @@
gap: var(--space-4);
overflow-x: auto;
padding-bottom: var(--space-4);
scroll-snap-type: x mandatory;
scroll-snap-type: none;
scroll-behavior: smooth;
/* Hide scrollbar for Webkit */
-webkit-overflow-scrolling: touch;
@@ -95,13 +95,58 @@
.album-grid .album-card,
.album-grid .artist-card {
flex: 0 0 clamp(140px, 15vw, 180px);
scroll-snap-align: start;
}
/* Horizontal rails can hold many off-screen cards; skip their paint/layout until visible. */
/* Horizontal rails (Home Discover, etc.): WebKitGTK + scroll — no content-visibility:auto,
no .card transition, hover pinned to cover, dim via overlay background not opacity. */
.album-grid .album-card {
content-visibility: auto;
contain-intrinsic-size: 0 240px;
contain: none;
transform: none;
transition: none;
}
.album-grid .album-card:hover {
box-shadow: inset 0 0 0 1px var(--border-subtle);
}
.album-grid .album-card-cover {
contain: layout style;
transform: none;
}
.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 .album-card-play-overlay {
opacity: 1;
background-color: transparent;
transition: none;
}
.album-grid .album-card .album-card-details-btn {
visibility: hidden;
opacity: 0;
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);
}
.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;
}
.album-grid .artist-card {
@@ -121,7 +166,6 @@
border: 1px dashed var(--border);
color: var(--text-secondary);
cursor: pointer;
scroll-snap-align: start;
transition: all var(--transition-base);
}
@@ -177,10 +221,13 @@
justify-content: center;
gap: 8px;
opacity: 0;
pointer-events: none;
transition: opacity var(--transition-base);
}
.album-card:hover .album-card-play-overlay {
.album-card:hover .album-card-play-overlay,
.album-card:focus-within .album-card-play-overlay,
.album-card:has(.album-card-details-btn:hover) .album-card-play-overlay {
opacity: 1;
}
@@ -196,12 +243,20 @@
font-weight: 600;
font-size: 13px;
cursor: pointer;
transition: transform var(--transition-fast), background var(--transition-fast);
pointer-events: none;
transition: filter var(--transition-fast), background var(--transition-fast);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
}
.album-card:hover .album-card-details-btn,
.album-card:focus-within .album-card-details-btn,
.because-card:hover .album-card-details-btn,
.because-card:focus-within .album-card-details-btn {
pointer-events: auto;
}
.album-card-details-btn:hover {
transform: scale(1.05);
filter: brightness(1.08);
background: var(--accent);
}
+6
View File
@@ -89,3 +89,9 @@ html[data-platform="linux"][data-linux-session="wayland"]:not(.no-compositing)[d
text-rendering: geometricPrecision;
}
/* Card play/enqueue overlays: opacity fade + GL layers can flutter on hover (mainstage). */
html[data-platform="linux"][data-linux-session="wayland"]:not(.no-compositing)
:is(.album-card-play-overlay, .song-card-play-overlay) {
transition: none;
}
+11 -3
View File
@@ -46,10 +46,12 @@
justify-content: center;
gap: 6px;
opacity: 0;
pointer-events: none;
transition: opacity var(--transition-base);
}
.song-card:hover .song-card-play-overlay {
.song-card:hover .song-card-play-overlay,
.song-card:focus-within .song-card-play-overlay {
opacity: 1;
}
@@ -64,12 +66,18 @@
align-items: center;
justify-content: center;
cursor: pointer;
transition: transform var(--transition-fast);
pointer-events: none;
transition: filter var(--transition-fast);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}
.song-card:hover .song-card-action-btn,
.song-card:focus-within .song-card-action-btn {
pointer-events: auto;
}
.song-card-action-btn:hover {
transform: scale(1.08);
filter: brightness(1.08);
}
.song-card-info {