<input type="checkbox" id="debug" />
<ul class="cards" id="cards">
<li id="card_0">
<img src="https://assets.codepen.io/89905/coverflow--Front-1024x1024.jpg" width="1200" height="1200" />
</li>
<li id="card_1">
<img src="https://assets.codepen.io/89905/coverflow--A-Thousand-Clouds-Front-Cover-1024x1024.jpg" width="1200" height="1200" />
</li>
<li id="card_2">
<img src="https://assets.codepen.io/89905/coverflow--Odd-World-EP-SMALL-1024x1024.png" width="1200" height="1200" />
</li>
<li id="card_3">
<img src="https://assets.codepen.io/89905/coverflow--Forest-Blue-Pre-LR-1024x1024.png" width="1200" height="1200" />
</li>
<li id="card_4">
<img src="https://assets.codepen.io/89905/coverflow--MOM-Remixes-1024x1024.jpg" width="1200" height="1200" />
</li>
<li id="card_5">
<img src="https://assets.codepen.io/89905/coverflow--ALONE-TOGETHER-remix-V71-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_6">
<img src="https://assets.codepen.io/89905/coverflow--Nature-Therapy-Pre-LR-550x550.png" width="1200" height="1200" />
</li>
<li id="card_7">
<img src="https://assets.codepen.io/89905/coverflow--Deep-Dive-Ambient-Edits-V8-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_8">
<img src="https://assets.codepen.io/89905/coverflow--Alpine-Koresma-x-Aroth-Artwork-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_9">
<img src="https://assets.codepen.io/89905/coverflow--Out-Of-the-Dark-Cover-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_11">
<img src="https://assets.codepen.io/89905/coverflow--2020-06-07-Marley-Carroll-Single-Blue-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_12">
<img src="https://assets.codepen.io/89905/coverflow--Deep-Dive-EP-Cover-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_13">
<img src="https://assets.codepen.io/89905/coverflow--Blackrose-Cover-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_14">
<img src="https://assets.codepen.io/89905/coverflow--FW-Imagine-Gold-Remixes2-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_15">
<img src="https://assets.codepen.io/89905/coverflow--We-Are-COVER-MAIN-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_16">
<img src="https://assets.codepen.io/89905/coverflow--Bath-House-Flat-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_17">
<img src="https://assets.codepen.io/89905/coverflow--Pronoia-JPG-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_18">
<img src="https://assets.codepen.io/89905/coverflow--Lapa9Theory-Cracking-Stores-no-Loci-logo-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_19">
<img src="https://assets.codepen.io/89905/coverflow--EMANCIPATOR_MOM_AlbumCover-2000px-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_20">
<img src="https://assets.codepen.io/89905/coverflow--MURGE-ep-cvr-3000x3000-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_21">
<img src="https://assets.codepen.io/89905/coverflow--Emancipator_Laybrinth-ART-01-4000x4000-at-300dpi-550x550.jpg" width="1200" height="1200" />
</li>
<li id="card_22">
<img src="https://assets.codepen.io/89905/coverflow--cover-550x550.jpg" width="1200" height="1200" />
</li>
</ul>
<div class="warning">⚠️ Your browser does not support CSS Scroll-Linked Animations, so this demo won't work. If you're feeling adventurous use Chrome 89 with “Experimental Web Platform Features” enabled. Alternatively you can <a href="https://twitter.com/bramus/status/1357391991114502144" target="_top" rel="noopener noreferrer">check out a recording of this demo</a></div>
/*
This is a JS based version of https://codepen.io/bramus/pen/xxRZZdK
It uses polyfills for css-typed-om and scroll-timeline
While it has some bugs on its own (it's not performant), it does render
the scroll timeline correctly. See bug 1 in CSS version for a description.
*/
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
:root {
--cover-size: 15rem;
}
@media (max-width: 800px) {
:root {
--cover-size: 9rem;
}
}
body {
background: #111;
min-height: 100vh;
font-family: sans-serif;
display: flex;
place-items: center;
}
.cards {
list-style: none;
overflow: scroll;
width: 100%;
white-space: nowrap;
scroll-snap-type: x mandatory;
outline: 1px solid #333;
background: rgba(0 0 0 / 0.5);
}
.cards li {
display: inline-block;
width: var(--cover-size);
height: var(--cover-size);
scroll-snap-align: center;
}
.cards li img {
dislay: block;
width: var(--cover-size);
height: var(--cover-size);
-webkit-box-reflect: below 0.5em linear-gradient(rgba(0,0,0,0), rgba(0,0,0,0.25));
}
.cards {
max-width: calc(var(--cover-size) * 6);
margin: 0 auto;
padding: calc(var(--cover-size) / 3 * 2) calc(50% - (var(--cover-size) / 3 * 2));
}
/* Show warning for older browser */
.warning {
position: fixed;
bottom: 1em;
right: 1em;
left: 1em;
padding: 1em;
border: 1px solid black;
z-index: 9999;
text-align: center;
color: black;
background: rgba(255 255 225 / 0.9);
display: none;
}
.warning a {
color: blue;
}
#debug {
position: absolute;
top: 1em;
left: 1em;
}
#debug::after {
content: " Show Debug";
margin-left: 1.5em;
color: white;
white-space: nowrap;
}
#debug:checked + .cards {
border: 1px solid lime;
}
#debug:checked + .cards li {
text-align: center;
color: white;
border: 1px solid blue;
}
#debug:checked + .cards li::before {
content: attr(id);
display: block;
position: absolute;
inset: 0;
line-height: var(--cover-size);
opacity: 0.5;
}
#debug:checked + .cards li img {
opacity: 0.5;
}
import { showDialog } from 'https://codepen.io/bramus/pen/ZEqMOLz/cccfe67c2b9cdfbeb5fb59083dbd0a64.js';
showDialog('https://scroll-driven-animations.style/demos/cover-flow/css/');
// Alternative Versions:
// - JS ScrollTimeline 2022: https://codepen.io/bramus/pen/MWVExQg
// - JS Motion One: https://codepen.io/bramus/pen/PoRKEaZ
// - CSS @scroll-timeline 2021: https://codepen.io/bramus/pen/xxRZZdK
// - JS ScrollTimeline 2021: https://codepen.io/bramus/pen/PobZbBV 👈 = The version you are currently looking at
// Polyfill for browsers with no Scroll-Timeline support
import 'https://rawcdn.githack.com/flackr/scroll-timeline/3063e156535f3ab1ffc8a4000ffdd3290232c121/dist/scroll-timeline.js';
const $ul = document.querySelector('ul');
const $lis = document.querySelectorAll('ul > li');
$lis.forEach(($li) => {
$li.style.perspective = '40em';
$li.style.position = 'relative';
// Create ScrollTimeline
const scrollTimeline = new ScrollTimeline({
scrollSource: $ul,
timeRange: 1,
orientation: 'inline',
fill: 'both',
scrollOffsets: [
{ target: $li, edge: 'end', threshold: 0 },
{ target: $li, edge: 'start', threshold: 0 },
],
});
// Animate <li>
new Animation(
new KeyframeEffect(
$li,
{
zIndex: ["1", "100", "1000", "100", "1"],
},
{ duration: 1, fill: "both" }
),
scrollTimeline
).play();
// Animate nested <img>
new Animation(
new KeyframeEffect(
$li.querySelector('img'),
{
transform: [
'rotateY(-45deg) translateX(-100%)',
'rotateY(-45deg) translateX(0)',
'rotateY(0deg) translateZ(1em) scale(1.5)',
'rotateY(45deg) translateX(0)',
'rotateY(45deg) translateX(100%)',
],
},
{ duration: 1, fill: "both" }
),
scrollTimeline
).play();
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.