August 26th, 2024 × #css#animations#scrolling
CSS: Scroll Driven Animations
Introduction to capabilities of scroll driven animations to create interactive effects based on scroll position by scrubbing existing CSS animations and keyframes over a scroll timeline instead of time.
- Scroll driven animations provide depth for web interactions
- Cards scale up & down based on scroll position
- Animations play over scroll timeline, not time
- Still uses CSS keyframes, scrubs through them with scroll
- Timeline can track element scroll or overall page scroll
- Scroll timeline visibly scrubs animation from 0-100%
- Animations happen off main thread so very smooth
- View timelines based on element visibility on page
- Fine tune start & end points of animation range
- Can customize timeline based on element entry point
- Supported in Chrome & Edge, with JS & CSS polyfills
- Gracefully degrade to no animations as progressive enhancement
Transcript
Scott Tolinski
Welcome to Syntax. On this Monday, hasty treat. We're gonna be talking all about scroll driven animations.
Scott Tolinski
We're gonna be giving you a little bit of an introduction as to what they are, what you can do with them, and just how incredible of an awesome new technology this is for the browser. My name is Scott Tolinski, and with me JS always is Wes Bos. What's up, Wes? Hey. Stoked to talk about this. It's such a cool
Wes Bos
API that's hit CSS and JavaScript.
Wes Bos
And, it's it's unreal, all the fun stuff you can do with it. I'm so stoked. This this
Scroll driven animations provide depth for web interactions
Scott Tolinski
one, view transition, starting style. There's so many cool new APIs. But this one in particular feels like it has a lot of depth into what you can accomplish with it. So I'm stoked to see some of the things that you you're gonna be talking about today. I'm also stoked to see my Sentry dashboard because it does not show any major errors at this time. Because guess why? We use Sentry to fix those errors on the Syntax website. So if you're having bugs and issues and stuff on your website, you need visibility into that, and you can get that with Sentry. So you just sign up for Sentry. You drop a a script in your site. Next thing you know, you're cruising. You're getting all your errors popping in. You're getting those stack traces. It's looking at your source maps. It's telling you exactly where the problem is and who's hitting that problem. Maybe there's an obscure bug with a 1 specific browser. You're gonna know what browser it is and where that bug is. You can go fix that thing. That way, people don't have an issue. So if you wanna check this out, head on over to century.i0forward/ syntax. Send them to get 2 months for free. Alright. Let's get into it. Scroll driven animations.
Wes Bos
Yeah. This is pretty exciting. So we had Bramus on the podcast a couple months ago, and he kinda talked a lot about that. But I thought we'd do, like, a an example of the actual API now that it's starting to hit the browsers. I've used it in a couple websites already myself, and I'd like I hit a couple bugs last week. Not bugs, but, like, I hit a couple, like, how do I do that? And, like, I've it caused me to really dive into the documentation as to how it all works and all the nitty gritty. And I was like, man, this is this is pretty flexible. So Wow. So you you used it on real things or just demos that you're you're experimenting? No. So my my TypeScript site that's coming up has I can even I can even show it to you. Here, let's start sharing the screen.
Scott Tolinski
Cool. I'll be stoked to see what you do for progressive enhancement here. This is one of the ones that I've been kind of staying away from. Oh, man. You are just you're too much, Wes. This is this is gorgeous looking awesome. So
Cards scale up & down based on scroll position
Wes Bos
the the idea here is that and you can see how the the cards are scaling up and scaling down as you scroll.
Wes Bos
Yes. I we should say that this has the potential to make a lot of very obnoxious websites.
Wes Bos
As with everything, once we get new tech, people are gonna abuse it. However, I think that animation can be very thoughtfully done. Animation can be done to add context. It can add to add cues to what's going on on the website. I think that this can be used for a lot of good, to make a better website experience, especially, like, when you look at a lot of the native stuff that Apple has.
Wes Bos
And and then we start seeing, like, oh, now we can do scroll driven animations on the web, and we have the view transitions being added and all this type of stuff. It's like, we want those.
Wes Bos
That's why people say web apps don't feel like native apps. A part of it is because of the this type of stuff. So these scroll driven animations are based on the CSS animations API. Both the CSS CSS animations API and the actual JavaScript animations API, and they work with both of them in this case.
Animations play over scroll timeline, not time
Wes Bos
And the way that it works is that well, there's sort of 2 ways that it works, and I'll get into that in just a second. But as you scroll, you're able to apply an animation to different elements depending on how far you've scrolled that element.
Wes Bos
So let's get into that. A lot of these examples are gonna be coming from scroll dash driven dash animations dot style. This is Bramus' website. He also has Wes really good video course that's,
Guest 2
like I think it's, like, an hour, hour and a half, or whatever that you could just blitz through to sorta get the idea of of how everything is working. So key frames in in CSS, it allows you to,
Wes Bos
spell out an animation. So you say at 0%, do this, at 50%, do this, and at a 100% do this. So you can say to, from, and you can make all of these different key framed animations with CSS.
Still uses CSS keyframes, scrubs through them with scroll
Wes Bos
And, normally, when you apply or when you turn on that animation, you give it a set of time. Right? You say, put this animation over 5 seconds, and then it go infinite or or repeat 3 times and then finish. The difference with this is that we still use CSS key frames, but instead of it playing itself over time, scroll driven animations play themselves over a time line that is controlled by your scroll. So you're sort of scrubbing through the animation, not with time, but with your actual scroll wheel. Now there are 2 new CSS properties that we need to know about. You you take all of your existing CSS animation knowledge with you, so all of your key frames, all of your easings, all of your film modes, all of your direction.
Wes Bos
All that stuff stays except for the the actual amount of time that the animation will play out, and we add 2 new animation properties, which is animation timeline and animation range. So let's first talk about timeline.
Timeline can track element scroll or overall page scroll
Wes Bos
Timeline defines if the animation is going to be controlled by how far you are scrolling an element or how far an element is on page. Right? So there is scroll, which is I have a DIV, and it can scroll from top to bottom. And I'm going to use that to go from 0 to a 100% of the actual element. So here's an example right here. I'm scrolling, and it goes from 0 to a 100%. Right? The other one, which I think is is even more useful, is how far you have scrolled on the actual page. Oh, sorry. I gotta make this a bit bigger so I can get the scroll bar.
Wes Bos
So you see this element right here, and it doesn't hit until it breaks onto the page very similar to, like, a intersection observer if you've used that into JavaScript API before. And then you see JS it scrolls through the page, you go from 0 to a 100%, and that then is scrubbing the animation as it goes on the page. And and that is really cool because you can say, as this thing is more on the page, then move the animation along throughout the timeline.
Scroll timeline visibly scrubs animation from 0-100%
Wes Bos
So scroll based timelines are based on how far an element is scrolled. This could be the body. This could be another element.
Wes Bos
And then you can also name a scroll timeline, which allows you to reference how far you are scrolled somewhere else in your CSS. So you could have a div. Like, for example, more commonly, the entire body of a page will be scrolled.
Wes Bos
Let's find an example that he has here.
Wes Bos
Reading progress indicator. Right? So JS you scroll through the page,
Scott Tolinski
you can show the progress indicator up at the top here. This is just a little red bar that goes from 0% wide to a 100% wide. And Yeah. And we should say on top of all of this because, you know, I don't know what it looks like on your end, Wes. But for me, when I'm looking at your screen recording here, it is a little choppy. It is very smooth. And if if you're seeing this and it has a lower frame rate by the time you're you're listening
Animations happen off main thread so very smooth
Guest 2
to this, I just wanna say it is very smooth. Yeah. And
Wes Bos
that's a a great point JS that the CSS scroll driven animations are not done on the main thread. So, previously, if you want to control something with a scroll, it had to be done on the main thread because you're literally listening for JavaScript scroll events and then passing that data to your CSS.
Wes Bos
Now that data of how far you are scrolled or how far into the view an element is is now available in CSS, so it can be done off the main thread, which means even more buttery smooth, animations.
Wes Bos
So the named Node, real quick, is if you want to be able to access how far somebody is on a scroll somewhere else, you can give that Scott a custom name. It's almost like a variable, has a dash in front of it, and you can then access it somewhere else in your CSS, kind of like a CSS variable, which is pretty nifty.
View timelines based on element visibility on page
Wes Bos
There's view based time lines, which is what I've been doing. Here's another example I have right here.
Wes Bos
These little cards right here, I want to to scale them up from 0 to a 100% over the first 50% of the viewport. So you can see how they're going from 0 to 50 percent as I scroll up. So this is referred to as a view based timeline, not because I don't care how far I am scrolled in this body here. I care how far each of the elements are on the page. And in this case, I'm I'm waiting for them to hit right about there to be a 100%. There's really cool set of dev tools that Bramus has also Node, which allow you to visualize where they are. So if I go to my dev tools here, see my scroll driven animations.
Wes Bos
Let me make this a bit bigger.
Scott Tolinski
And this exists within Chrome today, or is this something that I do install? A Chrome extension
Wes Bos
that you must install that's added to dev tools.
Wes Bos
But you can see, here's my card.
Wes Bos
And then as I scroll, it's showing me the view timeline is 11% in.
Scott Tolinski
And then So are those using viewport units or essentially the viewport present percentage?
Wes Bos
Yes. Let me let me show you the the code beside it. So the code here is animation time line is a view, so how far onto the page this element is, and then start when it breaks right onto the page, which is cover. I'll explain that in a sec. And then end, this is I I had to ask on Twitter, basically, how to do this JS Wes should the animation pnpm. And in our case, I want to end based on its entry point plus 50 viewpoint units. So you you you're saying 50% of the viewpoint, once it's hit that, then end the animation range. By default, it's going to be 0%. So if I just, like if I type, normal and normal here, as soon as it breaks onto the screen, it's going to be 0%. And then as soon as I'm fully scrolled right there, that's a 100%. Right? And I'm also using this with position sticky, which is why it looks a little bit funny, and that's why I had to use that animation range. And so let's look at the actual value here. So let's look at the view ranges visualizer, because we talked about animation time line, which is is it based on scroll or view? And the other property we have is animation range.
Wes Bos
So, basically, where does the view timeline start and finish? So if we take a look at the the this example right here, by default, it's gonna be cover, cover 0 to a 100%, meaning that the animation is going to start as soon as the element cracks onto the screen.
Fine tune start & end points of animation range
Wes Bos
JS soon as it peaks its 1st little Vercel above the fold, it starts at 100%. Pixel.
Wes Bos
Yeah. And then it shows all of its Vercel. And then as soon as it poops its last little pixel off the screen, it gets to a 100%. Right? So that's the default if you wanna animate something all the way up. But in many cases, you don't want your element to be fully animated once it's off the screen because a lot of times, you're simply just scaling up or sliding in from the side or doing something like that. So you can change those values from cover to contain. So contain is different than cover in that it must be a 100% peaking its pixels on the screen before it before it will even start itself.
Wes Bos
It feels like they thought of everything It is. With this API. That's what I that's the problem I had. I was like, oh, like, how do I how do I base this? My problem Wes, like, okay. I want it to start cover. Like, as soon as it starts peaking on the screen, I want it to Scott, but then I want it to finish, like, kinda, like, halfway through. Right? So what I had to do is I had to change the animation timeline, so I changed it based on its entry.
Wes Bos
And then in this case, there's you can only do percentage, but you can use anything. You can calc. You can use a variable.
Wes Bos
If it's in JavaScript, you can put a JavaScript value in there. My case, I did 50 view port height units, but I think I can do something like 50%. Oh, that's that'll show me 5th once the element is 50% on, then it will start to animate itself. So that that could also be helpful as well.
Can customize timeline based on element entry point
Wes Bos
And there's, again, there's entry entry crossing. So as soon as it cracks that on and then exit and exit crossing for the additional values there.
Guest 2
Wow.
Wes Bos
Other cool examples is I did a little TikTok on this one right here, which, whoo, this is just using CSS, if if you can believe it or not. But this is a a this is an SVG path that is sort of scribbled on the screen, and then we are changing the stroke offset on that SVG
Scott Tolinski
from you can go from 0 to 1. Mhmm. And It's the classic SVG draw on technique. Yes. If you've ever seen SVGs that, like, draw themselves on, you're just attaching that offset to a scroll position.
Wes Bos
Exactly. And previously, you had to do that in JavaScript, but now you can simply do it in CSS.
Wes Bos
And the the animation draw where's the key frame here? Here we go. The key frame is simply just stroke dash offset 0. So, basically, go from your default, which is 1, to 0, and it will then draw itself as I scroll the thing into view, which is wild.
Wes Bos
So much really cool stuff you can do with it. I certainly really clicked for me when I checked out this tool that Bramas made because you can change the values and sort of visualize it. And then when I was debugging everything, I saw I had to go into the dev tools for scroll driven animation to really see, okay, where does the browser think this is at right now? So really good tooling around this, really good demos on here, some really good videos from Bramas, and, I think it's going to be very helpful. It is only in what's the values right now? So it's only in Chrome and Edge right now. However flag. There is a no. It's not even not even behind the flag.
Scott Tolinski
According to can I use, it's behind a flag?
Supported in Chrome & Edge, with JS & CSS polyfills
Wes Bos
Really?
Scott Tolinski
I Maybe that's animation.
Scott Tolinski
Maybe not animation range.
Scott Tolinski
Okay. Yeah. No. This shows it. What was I looking at? I was looking at scroll driven oh, scroll timeline. Sorry. That's what I was looking at.
Wes Bos
Oh, okay. That is 4. Yeah. Oh, yeah.
Wes Bos
So pretty exciting. There is a polyfill both for the JavaScript and for the CSS, so you can use it today. Or you can go ahead and and start to use it. The other thing is you it it is progressive enhancement, meaning that if you it doesn't work, your elements are simply just on the page. You know? Just make sure they are on the page here. Let's let's take a look at this example over here. Let me open up Firefox.
Scott Tolinski
What's interesting, Wes, is that can I use shows scroll timeline as being behind a flag, but MDN and baseline show it as being available in Chrome? So I think this might be a situation where can I use is,
Wes Bos
9? Starting to see that. Now that there's, like, 2 of them, you're starting to see the the information being a little bit out of out of date or out of sync. But the so this is the example in Firefox where it is not supported, and it the escalator is simply stairs. Right? Look at that. It still works just fine.
Wes Bos
The elements just do not scale up on their way in.
Scott Tolinski
So, again, it's something that Node start to use. Sorry, Wes, to cut you off. If you wanna further enhance progressively enhance this, let's say you weren't happy with the way this looks, you could always use a, like, supports query to know if the browser supports this feature. And if it doesn't support this feature, you can
Wes Bos
adjust your layout accordingly. Yeah. Exactly. Yeah. Maybe you don't want them off page. Or if you if you do have to put, like, an initial
Gracefully degrade to no animations as progressive enhancement
Scott Tolinski
animation value in it oh, one more thing. You just want them grouped together in a different layout entirely. Right? Yes.
Wes Bos
Very doable. One more thing, which this blew my mind, is Dave Rupert has a blog post about how he used scroll driven animations to give a table a shadow, with position sticky. And I thought that this this is wild because in CSS, we've always wanted a stuck selector.
Wes Bos
When this thing is in its stuck position, like a position sticky, but once it's stuck to the top or or to the bottom or wherever you're sticking it, in this case, he is sticking the 1st column of the table so that when he scrolls, the names of the columns will stay there, and the rest will go underneath it. That's a great use case for position sticky. However, if you wanna style them differently based on when they are stuck and unstuck, you have to use, like, a a resize observer to check if it's stuck or not. And you can use a little bit of a a hack here where you can basically just set the last state of the key frame to be the stuck Scott, and I even tried it. I went a little bit further. So if you still want an animation, you can animate up to 99% and then put your stuck state in the 100%, which is is pretty nifty. I think I still would like a a stuck state in CSS without JavaScript, but this is that's pretty close with without any JavaScript.
Scott Tolinski
That's something we've all had to do quite a bit. I mean, I I feel like I've run into that situation a ton. You're building any sort of scrolling area that's contained. You kinda want those shadows in there to indicate there's more data here than you might be seeing. Yeah. Or, like, a fixed header as well. You Node, you wanna you wanna throw a little shadow or you wanna style it differently.
Wes Bos
Super easy. Actually, let's let's try the scroll driven on Firefox.
Wes Bos
Look at this. Let's this is Firefox. It doesn't it's not supported.
Wes Bos
The website works fine. Yeah.
Wes Bos
Just fine because of the the polyfill has been loaded.
Wes Bos
So let let me show you the stuck header.
Wes Bos
Where's the fixed header? Oh, this one's cool. The fly in contact ESLint? Oh, no. He doesn't have it. He doesn't have the polyfill loaded on on the all the examples.
Wes Bos
Shoot.
Wes Bos
Oh, this one, he has a polyfill loaded right here.
Scott Tolinski
Cover flow. That's in Firefox with a polyfill? Yeah.
Scott Tolinski
So what's the downside to using the polyfill?
Wes Bos
Probably that it's it has to run it. It's probably using resize or not intersection observer, and it's running on the main thread.
Wes Bos
So,
Scott Tolinski
certainly, you can have it. You know, if you're only serving that polyfill with people who need it, then Yeah.
Scott Tolinski
Yeah.
Scott Tolinski
Or you just you just fall back to no animations. Man, the options are way better for this than I was expecting. When when we when we had this episode on the calendar, I was thinking, I I was taking the role of the classic CSS commenter.
Scott Tolinski
Great. But I can't use it. And now I'm stoked to learn I can't when you told me that you were using this in a real site, I could not believe it. Now I gotta get moving on this right now. I gotta in fact, I gotta we we're canceling the rest of the episodes. I gotta spend some time on scroll driven animations.
Wes Bos
Pretty exciting stuff.
Wes Bos
That's that's all we have for today. Hopefully, it gives you a good idea of scroll driven animations. We got the view. We got the scroll. You've got your key frames that are scrubbing them and then a whole bunch of options to tweak them here and there.
Scott Tolinski
Sick. Wow. That's amazing. I'm I'm really stoked for this.
Wes Bos
Alright. We'll catch you later.