I’ve seen all the excitement about scroll-driven animations. I’m excited too. Animations that use scroll position as a timeline rather than a time-based duration is just a clever idea. It’s something that websites have been using probably-too-much JavaScript for for a long time and it’s nice to see that kind of thing move to CSS where it belongs.
But I haven’t gotten a chance to play with it directly very much yet. So here I go!
This all got started because I got a nice email from a reader who had a very specific effect in mind they were trying to replicate on their own website. Somewhat inspired by Chung-Yun Yoo’s website, the idea is: images that zoom in (or out) as you scroll. They don’t change dimensions themselves, they just change how much of the image you can see in the space they already occupy. This doesn’t require too much trickery — you just set the width
, height
, and background-size
and you can affect how much of an <img>
you can see. Changing that background-size
has the zooming affect.
This is what we’re after (video):
The trick is changing the background-size
on scroll. This is normally something you’d use JavaScript for, like scroll
event listeners on the document and/or IntersectionObserver
stuff. But now, we can express what we want in Scroll-Driven Animations.
Bramus Van Damme has lots of good resources on Scroll-Driven Animations like this article and the site scroll-driven-animations.style. The tool I found most helpful when trying to figure this out was this View Progress Timeline tool. In this tool, you can see how a green box has an animation run only during the time when it’s visible at all in the viewport. I was very pleased to have that click for me, as before I saw this I thought that the timelines needed to be the entire scroll-length of the element. Good job, API!
Note the cover
keyword there that is helping us achieve that effect. It’s definitely worth a play with the other values to see what they do. Honestly I can imagine they are all useful in certain situations. Seeing the generated code, I was able to see that our image effect is quite simple to scaffold:
.img {
animation-range: cover 0% cover 100%;
animation: the-animation linear;
animation-timeline: view();
animation-iteration-count: 1;
}
@keyframes the-animation {
from {
/* whatever */
}
to {
/* whatever */
}
}
Code language: CSS (css)
In our case, we can flesh out the animation with just some background-size
changes and we’re good! Here’s a basic demo you can scroll up and down:
As I write, scroll-driven animations are available in Chrome ‘n’ friends, flagged in Firefox, and not yet available in Safari. There is a polyfill, which that demo above loads, so it should work across all three.
Those are the basics that achieve what I had in mind. Now here’s a Pen that uses the same animation across multiple elements, but sets where the animate to via CSS Custom Property.
Funnnnn.
Very cool – sadly It doesn’t look the polyfill-works on iOS 16 safari,