Weekend in Lisbon
Three days of tiles, tarts and trams.
Three album covers in the classic cover flow pose, the side ones turned inward and set back. On hover they swing flat and spread into a row. Each cover is one element with its own 3D transform.
Also known as: coverflow css, 3d album covers hover, angled gallery straighten.
<div class="hfx-cover-flow"> <div class="hfx-cover-flow-cover"><span>Tides</span></div> <div class="hfx-cover-flow-cover"><span>Night Drive</span></div> <div class="hfx-cover-flow-cover"><span>Neon</span></div> </div>
.hfx-cover-flow {
--c: var(--hfx-color, #3b82f6);
font-size: var(--hfx-size, 16px);
position: relative;
width: 18em;
height: 5.6em;
perspective: 30em;
font-family: system-ui, sans-serif;
}
.hfx-cover-flow-cover {
position: absolute;
top: 0;
left: 50%;
display: flex;
align-items: flex-end;
width: 5.6em;
height: 5.6em;
margin-left: -2.8em;
padding: 0.5em 0.6em;
border-radius: 0.3em;
color: #fff;
font-size: 1em;
box-shadow: 0 0.6em 1.2em color-mix(in srgb, #000 20%, transparent);
transition: transform 0.6s cubic-bezier(0.3, 1.2, 0.5, 1), filter 0.6s ease;
}
.hfx-cover-flow-cover span {
font-size: 0.7em;
font-weight: 700;
letter-spacing: 0.04em;
}
.hfx-cover-flow-cover:nth-child(1) {
background:
radial-gradient(circle at 35% 35%, #fef3c7 0 0.9em, transparent 0.95em),
linear-gradient(transparent 60%, color-mix(in srgb, var(--c) 60%, #000) 60%),
linear-gradient(color-mix(in srgb, var(--c) 30%, #fff), color-mix(in srgb, var(--c) 70%, #fff));
filter: brightness(0.85);
transform: translateX(-4.3em) translateZ(-1.6em) rotateY(52deg);
}
.hfx-cover-flow-cover:nth-child(2) {
z-index: 1;
background:
repeating-radial-gradient(circle at 50% 42%, transparent 0 0.3em, color-mix(in srgb, #fff 14%, transparent) 0.3em 0.36em),
radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--c) 60%, #fff) 0 0.8em, transparent 0.85em),
linear-gradient(160deg, color-mix(in srgb, var(--c) 55%, #0f172a), color-mix(in srgb, var(--c) 20%, #020617));
transform: translateZ(0.6em);
}
.hfx-cover-flow-cover:nth-child(3) {
background:
repeating-linear-gradient(135deg, color-mix(in srgb, var(--c) 80%, #000) 0 0.5em, var(--c) 0.5em 1em);
filter: brightness(0.85);
transform: translateX(4.3em) translateZ(-1.6em) rotateY(-52deg);
}
.hfx-cover-flow:hover .hfx-cover-flow-cover:nth-child(1) {
filter: brightness(1);
transform: translateX(-6.1em) translateZ(0) rotateY(0deg);
}
.hfx-cover-flow:hover .hfx-cover-flow-cover:nth-child(2) {
transform: translateZ(0);
}
.hfx-cover-flow:hover .hfx-cover-flow-cover:nth-child(3) {
filter: brightness(1);
transform: translateX(6.1em) translateZ(0) rotateY(0deg);
}
@media (prefers-reduced-motion: reduce) {
.hfx-cover-flow, .hfx-cover-flow *, .hfx-cover-flow::before, .hfx-cover-flow::after, .hfx-cover-flow *::before, .hfx-cover-flow *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--hfx-color on the element or a parent.
Currently previewing #3b82f6.--hfx-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 16px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.