Loading video...

Video Failed to Load

Go Home

Card stack using scroll-driven animation w/ snapping. Just a few lines of JS, zero dependencies. Code + demo via CodePen.IO

84,128 views • 2 years ago •via X (Twitter)

34 Comments

Pontus Wellgraf's profile picture
Pontus Wellgraf2 years ago

@paul_uiux @CodePen Absolutely amazing! Feels so good 🔥 Just a heads up, it looks like with the touchpad interaction (Swiping wasn't supported), only the first cards gets put behind the stack whereas all other repetitions just scews the stack and hard cut to the next card

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen Gotcha! That’s sounds like it’s not updating the active index which requires scroll snap events (Chrome 129+)

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen Chrome 129’s rolling out now I think so try updating or try on Chrome Beta?

Pontus Wellgraf's profile picture
Pontus Wellgraf2 years ago

@paul_uiux @CodePen I see! Just updated but still feels a little strange sometimes - See video for reference It feels like it's every time you don't wait until the transition has finished when the whole stack scews oddly. Maybe the ease out should be shortened and finish earlier to avoid this

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen Ah yeah, that’s not right 🤨 The scroll snap change fires only when the animation has completely finished. Not ideal but if you try moving through slowly (and waiting a fraction after the out transition) I think it should all look ok

Pontus Wellgraf's profile picture
Pontus Wellgraf2 years ago

@paul_uiux @CodePen It does work if I wait! I just felt it was finished but the ease out is very slow in the end. I think if the transition of the cards went behind the stack faster and with less delay, this would solve this and various swipe speeds 🚀

Umxr K's profile picture
Umxr K2 years ago

@paul_uiux @CodePen Just brilliant art

Dennis Landi's profile picture
Dennis Landi2 years ago

@paul_uiux @CodePen Hi Paul, the codepen isn't working for me. The mouse swipe isn't working and the whole thing is stationary. Head's up.

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen Hey! Can you try touch pad swipe?

Dennis Landi's profile picture
Dennis Landi2 years ago

@paul_uiux @CodePen Hi. Yeah, it does work with the touchpad and the middle button pressed on my PC laptop. And it works on my phone. But...Can you getting working with a normal mouse?

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen We can bind mouse drag *but* when the mouse is released it’ll snap immediately (no smoothing animation to the closest snap point)

David K 🎹's profile picture
David K 🎹2 years ago

@paul_uiux @CodePen This is incredible!

Robera Geleta's profile picture
Robera Geleta2 years ago

@paul_uiux @CodePen Glad to see this memed

mirko_ddd ⁝'s profile picture
mirko_ddd ⁝2 years ago

@paul_uiux @CodePen The tilt on Y axes makes the difference, feels so real. Congratulations 👏

James Vreeken's profile picture
James Vreeken2 years ago

@paul_uiux @CodePen not as cool as yours but works with without scroll snap. you are an inspiration!

Gustav Ekerot's profile picture
Gustav Ekerot2 years ago

@paul_uiux @CodePen Impressive! I've tried doing something similar before so I know how much effort it takes, good job!

_Tush_'s profile picture
_Tush_2 years ago

@paul_uiux @CodePen Cool !

Hussain Khan's profile picture
Hussain Khan2 years ago

@paul_uiux @CodePen Very nice 👏

Valerio Leo @ Raycash ☀️'s profile picture
Valerio Leo @ Raycash ☀️2 years ago

@paul_uiux @CodePen This is brilliant. Are you planning to make it a npm package?

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen Thanks! It’s using features that aren’t available in most browsers (Safari doesn’t support scroll driven animation at all, yet) so it probably wouldn’t work as a package. Maybe in a few years?

Tanvir's profile picture
Tanvir2 years ago

@paul_uiux @CodePen Bird love your cards 😁

Artur Minin's profile picture
Artur Minin2 years ago

@paul_uiux @argyleink @CodePen Look so cool! Works like this really insipire me to dive deep into CSS

Oleg | webstudio.is's profile picture
Oleg | webstudio.is2 years ago

@paul_uiux @CodePen Amazing! Reaction to swipe is slightly too fast, would expect more distance before it changes to the next one

Lars Ejaas 👨‍💻's profile picture
Lars Ejaas 👨‍💻2 years ago

@paul_uiux @CodePen Love it! Scroll-driven animations using the new scroll-timeline is mind-blowing 🤯 Most frontend devs do not realize how much you will be able to do using only HTML and CSS with this! Love what you accomplished here with this new API ✨️ 🙌

Ricky Raihan Azhari's profile picture
Ricky Raihan Azhari2 years ago

@paul_uiux @CodePen i can't use it in mobile, 😮‍💨 i think it needs a few lines again

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen Sorry, Safari doesn’t support scroll based animations

Ricky Raihan Azhari's profile picture
Ricky Raihan Azhari2 years ago

@paul_uiux @CodePen

Michal Malewicz's profile picture
Michal Malewicz2 years ago

@paul_uiux @CodePen Wow this is cool! ❤️❤️

ST's profile picture
ST2 years ago

@paul_uiux @CodePen beautiful.

Slo's profile picture
Slo2 years ago

@paul_uiux @CodePen Lord this is so good!!!

Abdullah Khalid Omi's profile picture
Abdullah Khalid Omi2 years ago

@paul_uiux @CodePen with drag enabled for the desktop, it would be cool!

Paul Noble's profile picture
Paul Noble2 years ago

@CodePen Yeah, agree! Unfortunately we can bind mouse drag events to scroll but on mouse up the scroll snaps immediately at the next snap point (no animation)

Madhu's profile picture
Madhu2 years ago

@paul_uiux @CodePen @pavan_1827

HoverHacks's profile picture
HoverHacks2 years ago

@paul_uiux @CodePen wow that's awesome!

Related Videos

CSS Tip! 🚥 You can create these trending expanding scroll indicators with scroll-driven animations and flex 🤙 .indicator { animation: grow; animation-range: contain calc(50% - var(--size)...; animation-timeline: var(--card); } @​keyframes grow { 50% { flex: 3; }} What's the trick? Put the indicators in a container using flex layout and set a width larger than the number of indicators 😉 .indicators { aspect-ratio: 7 / 1; display: flex; } Importantly, set no gap 🤏 To mimic the gap set a transparent border on each indicator and set the background using padding-box .indicator { background: linear-gradient(#​fff, #​fff) padding-box; border-radius: 50px; border: 4px solid transparent; } Now for the animation. You want to create a view-timeline for each card that moves across 🤙 li:nth-of-type(1) { view-timeline: --one inline; } li:nth-of-type(2) { view-timeline: --two inline; } Make sure they use the inline axis too! The trick is hoisting these view-timeline so the indicators can use them with timeline-scope 👀 .track { timeline-scope: --one, --two, ...; } All that's left is for you to create the animation piece using some calc with the card size ⚡️ .indicator { --size: calc(var(--card-width) * 0.9); animation: grow both linear; animation-range: contain calc(50% - var(--size)) contain calc(50% + var(--size)); } .indicator:nth-of-type(1) { animation-timeline: --one; } .indicator:nth-of-type(2) { animation-timeline: --two; } @​keyframes grow { 50% { flex: 3; }} And there you have it, responsive scroll indicators using CSS scroll-driven animations 😎 Sprinkle a little JavaScript to make them clickable and scroll the the right card ✨ const shift = (event) => { if (event​.target.tagName === "BUTTON") { const index = [...event.target.parentNode.children].indexOf(event​.target); const item = document.querySelector(`li:nth-of-type(${index + 1})`); item.scrollIntoView({ behavior: "smooth", inline: "center" }); } }; As always, any questions or suggestions, let me know. I've put a JavaScript fallback in to use GSAP in browsers that don't have scroll-driven animations 🫶 CodePen.IO link below! 👇

jhey ʕ•ᴥ•ʔ

575,728 views • 2 years ago