Main

CSS-Only Scroll-Driven Animation and Other Impossible Things

Wait, you can’t do scroll-driven animation with just CSS, right? Bramus will show us that not only is it possible, but there’s even more that CSS can do these days. Upcoming episodes: https://lwj.dev/schedule Links & Resources: - https://twitter.com/bramus - https://www.bram.us/ - https://scroll-driven-animations.style/ - https://codepen.io/jlengstorf/pen/BavGKjv - https://scroll-driven-animations.style/tools/view-timeline/ranges/#range-start-name=cover&range-start-percentage=0&range-end-name=cover&range-end-percentage=100&view-timeline-axis=block&view-timeline-inset=0&subject-size=smaller&subject-animation=reveal&interactivity=clicktodrag&show-areas=yes&show-fromto=yes&show-labels=yes - https://chromewebstore.google.com/detail/scroll-driven-animations/ojihehfngalmpghicjgbfdmloiifhoce?pli=1 - https://codepen.io/jlengstorf/pen/mdaQPjv - https://codepen.io/jlengstorf/pen/LYMXZEg - https://kizu.dev/ - https://www.learnwithjason.dev/schedule/ Watch future episodes live at https://twitch.tv/jlengstorf This episode was sponsored by: - Netlify (https://lwj.dev/netlify) - Vets Who Code (https://lwj.dev/vetswhocode) Live transcription by White Coat Captioning (https://whitecoatcaptioning.com/) 00:00:00 - Welcome 00:01:15 - Who is Bramus? 00:02:47 - How deep can you go with CSS? 00:06:55 - What are the most exciting parts of CSS? 00:12:00 - What is a scroll-driven animation? 00:20:10 - Example of scroll driven animations 00:26:45 - Using Carousel step indicator 00:33:23 - Getting started with scroll-driven animation on CodePen 00:41:47 - Using a calc function to animate smoother 00:44:32 - Adding a fade out 00:46:05 - What is the fill mode in animation? 00:48:58 - DevTools extension 00:55:46 - Building a cover card to fixed header animation 01:15:14 - Scrolling sections in the opposite direction 01:27:28 - Where can I learn more about scroll-driven animations with CSS?

Learn With Jason

5 months ago

JASON: Hello, everyone. And welcome to another  episode of Learn with Jason. Today on the show, we've brought on Bramus. How are you doing? BRAMUS: I'm doing great. How are you, Jason? JASON: How do you like that pronunciation?  I'm going to get it just right. BRAMUS: I have a few pronunciations,  I say Bramus with the long A, and in English, it becomes Bramus or Bromise -- JASON: It's unfortunate. I have the  American problem of being completely unable to roll an R. Everything sounds  like I've
got marbles in my mouth. BRAMUS: The good thing is  I work mostly with American and English-speaking people.  I'm used to it, no worries. JASON: You're used to just having  your name completely butchered. BRAMUS: Yeah. JASON: I apologize. So, all right. So, I  am so excite to have you on the show. This is gonna be a lot of fun. We're talking about  one of my favorite things in the entire world which is playing around with CSS. And I just  can't wait. But before we talk about that, let's talk a
little bit about you. For folks  who aren't familiar with you and your work, do you want to give us a bit  of a background on yourself. BRAMUS: I'm Bramus, or Bramus, it depends. And  I'm a Chrome developer relations engineer at Google. I'm involved mainly with CSS and web UI.  That's all of the new CSS stuff that is coming. But also some new web UI stuff, for example.  The select list item. The details element that's getting like some love. And it's gonna ship  like soonish-hopefully. So, yeah.
That's what I'm concerned with. And before that, I always -- I was  a web developer in the past 20-ish years I have been doing web development, backend, frontend,  whatnot. But my passion was always CSS. So, yeah. That's what eventually got me in at Google and  that's what I'm doing now as my day-to-day job. JASON: I love it. I can't imagine something I  would enjoy more than being able to collect a paycheck to play with CSS and like stress test  it and make it better for the platform. So, you
are -- you're doing one of my dream jobs  over there. So, I'm actually -- I'm curious because I feel like -- and this is not me  trying to start a debate. Because I -- I know this is kind of a touchy topic. But like  there's that sort of pervasive belief that CSS is somehow less-than when it comes to writing  other programming languages. And that's never sat right with me because I feel like of  all the things that have challenged me, getting CSS to do the thing that  I see in my head is -- is s
o much more of a programming exercise to me  than when I'm trying to, you know, make logic work in JavaScript or something like  that. So, as you've sort of made this your career, how -- how deep does the rabbit hole go on CSS?  You have been doing it for years now. Like do you feel like you're done? You've learned it  all? Or like how much further is there to go? BRAMUS: I feel like I need to learn -- I still  need to learn like a ton of stuff. It's only whether you start like digging into cert
ain  things. And now also part of my job. That you start learning all like the little details and  intricacies about something. Like the cascade, for example. It's part of name, right? Cascading  style sheets. It's on the when you start digging deep, oh, there's this little detail over here.  Oh, that's how it works. Before I was taught, cascade, you have the origins and specificity with  the numbers and that's it. Well, there's quite a lot to learn about it. And that's just that little  part of
CSS. Because CSS has exploded over the years with many new specs coming. Like Flexbox  play out. If you transition, scroll animations. All the positioning things you can do. Yeah,  it's a very, very deep rabbit hole to go into. JASON: Yeah, absolutely. This is sort what have I  have been noticing from myself at least is that I felt for a long time when I was younger that, you  know, there was -- there was kind of like a point where you would be done learning something.  Where you could learn it
. And you would, you know, I don't know, hit the end of the  manual or something and as long as you knew all the things in the manual, I'm finished. I  know this forever now. And as reality set in, as I got deeper and deep entire my career, I just  realized that even if you are the leading expert on a certain subject, there is still always one  more thing to learn. And then when you learn that thing, it answer -- it opens a question. And then  that's one more thing to learn and you just -- you c
an never really run out of things to learn  or try. And as people, you know, use a thing, it evolves. And that's actually been one of  the most fascinating things for me to watch is from the late '90s when I first became aware  of the web and of building websites to the early 2000s when I started doing it professionally to  today, CSS has gone from not existing to becoming something that was -- I would say rudimentary in  the early 2000s. It was like, it does -- you know, it does enough. We can
get some font changes, we  can get some colors. To today we can do -- I saw somebody built a Morse code decoder in pure CSS.  It absolutely melted my brain trying to figure out how it worked. And we're seeing stuff like,  you know, people are building these incredible 3D models. Building unbelievable things. People  like Lynn Fisher are doing CSS art. Full-blown oil painting lookalikes in CSS. And I saw some  work from you when Una was on the show recently, she was showing me a bunch of scroll-d
riven  animations that were built completely in CSS. And if you told me three years ago that you  were going to try to build a CSS animation in pure CSS -- or a scroll-driven animation in pure  CSS, I would assume that you didn't know how the web worked. There's no way. You can't do that.  It's impossible. And yet here we are. And it's working. So, tell us a little bit about this.  Like how -- I mean, first of all, like I kind of made an assumption that scroll-driven is the  biggest thing you fo
cused on. But like what are you finding to be the most exciting parts of  CSS as its evolved over the last few years? BRAMUS: The most exciting parts I think  are the -- like the non-default uses of a certain technology. And like  you've mentioned Lynn Fisher, you mentioned I paintings for example. And I  see Jane is also in the chat. Like, for example, they launched the space toggle hack. It uses  custom properties and it's like a switch you can flip on or off. And that invention, because  it i
s an invention, led to many more other things that you can do with CSS. And that's -- that's  so cool. Same thing with scroll over animations, for example. You've already mentioned it.  But way to do way more than scroll-over animations. Maybe later in the show, maybe  some uses for scroll-driven animation. JASON: I have never heard of this space toggle.  And now Jane, if you want to come teach me things, hit me up. I would love to learn  about this invention. Okay. So, scrolling is kind of intr
insically an action  that to me feels like it is outside of the style, right? But it does affect the way that the page  looks because you're moving things up and down. And a huge part of CSS recently has been figuring  out ways to manage transitions. Figuring out ways to do keyframe animations and -- and this is, you  know, to me this has been a very interesting like where do you draw the line between what should and  should not be in CSS? And so, you've been in this world for a while. Like how
did this conversation  go when the discussion about trying to get scroll triggers into CSS, like was it -- was it kind  of a unanimous like, yeah, that makes sense? Or was there a lot of pushback, like, no, we  shouldn't bring that sort of thing into the spec? BRAMUS: So, the initial discussions on this  predate my time at Google. Because I dug a bit like -- because now I have access to some  internal docs. And like some of the earliest conversations date back to more than 5 years ago.  Engineer
s already thinking about it at the time. And it was part of the Houdini effort. They wanted  like an animation worklet to do something. Oh, yes, and you could attach it to scroll as  well. And that kind of made the thing. But that little part went nowhere. That  big chunk went nowhere. But the small part of scroll-driven animations. Like  that idea continued to move on and be, yeah, get evolved. And like I think three  years ago we had a working implementation using an @scrolltimeline rule. But
it was  working, that feels very un-CSSy. You can see, it was like a JavaScript-type of solution that  was then transformed to, oh, we need to do this in CSS. Let's invent an @scroll timeline rule.  It was a JavaScript to CSS translation. But it was working. You need to rewrite things. That's  around the time when I joined Google. So, I have been part of the spec writing process and giving  suggestions. Oh, maybe this should be easier and this should be done. Yeah. And we have it now. It  shippe
d in Chrome 150, which is amazing, I think. JASON: Yeah. And is this -- I guess  as a like a first level setting, is this something that I can  use cross-browser right now? BRAMUS: So, the answer is "No." Because Chrome  right now is the only browser to support it. Firefox, however, is working on implementation.  That's very good news. Then WebKit, Safari, expressed their support for the API. Okay.  We like this API. Or we can agree that it's useful. And maybe someday we'll implement it.  That's
basically what they are saying. So, it's no guarantee that we will have it this  year or next year. Who knows? Time will tell. JASON: Gotcha. BRAMUS: It's only supported in Chrome. But all  browser vendors are on board which is one very good thing. And then the other great thing  about scroll-driven animations is I mostly I use them as a progressive enhancement. They are  not essential to how the website should work. So, if my CSS doesn't load or my browser doesn't  support scroll-driven animat
ions, you still get to see the style thing, but it won't animate  on scroll. And that's not that bad, I think. JASON: Yeah. That makes sense. Okay. So,  I realize -- I just jumped right into talking about the history of this. And I never  actually asked you to define what it is. So, for somebody who is just hearing this term for  the first time, what is a scroll-driven animation? BRAMUS: The name kind of should say  itself. But that's going to -- so, it's an animation driven by scroll. So, think
  of a CSS animation or one created using the web animations API. And when you use it, and you  go to page, you have a web animation on there, or a CSS animation, it will load and start  running. And the document timeline. So, when the page loads, document timeline starts  at zero and then goes one second, two seconds, three seconds, and so on. And with scroll-driven  animations, you say, hey, don't run this animation on the document timeline. But run it on a certain  scroll timeline. And that m
eans that if you are at the very top of your scroller, you are at  zero percent progress. And if you scroll all the way to the end of your scroller, you  are at 100% of your scroll process. So, your animation will move as you scroll up and  down. Ergo the same, scroll-driven animation. JASON: This is -- what I love about this is  that it gives us this capability as Devs to have some -- like -- have an animation that's  not just kind of playing on a loop. But that it's moving as the user moves. A
nd if you go down  the page a little bit and then back up, you know, the animation will kind of like go back and forth  with you and we've seen this in like product demos, you know? Where you look at the classic  like Apple marketing style page. Where if you scroll down the page, the computer spins into  view and zooms? And zooms out. And previously, these were absolutely monstrous passage. Like  they were huge, multiple, multiple mega bytes, tons of JavaScript. Part of that is because the  imag
es are enormous. You can't make the images small when they're that high res. Well, you  can. But that's a different topic. But with that being said, a lot of it was dedicated  to loading these big JavaScript libraries and then you have to do a lot of like observing the  window and looking at where the user is. And it just -- it gets very heavy. And so, what you're  saying is that with this scroll-driven animation, if I -- if I want to make one of those where I'm  doing a product demo and got stu
ff spinning in and zooming out. I could do this on my -- I could  do this on my own site without JavaScript now? BRAMUS: Yeah, exactly. JASON: Cool... BRAMUS: The cool thing is because these  scroll-driven animations, they work in conjunction with the existing CSS animations and  web animations. And those animations already know how to run things on the compositor. So, off the  main track. Which means that you will have more time for other JavaScript to run. Like you said  before, you need to ha
ve like a scroll progress listener, which uses some blocking JavaScript.  Then needs to take the scroll offset. Oh, yeah, you're this far into the page. That's  this much percent. And so on. You no longer need that. Scroll-driven animations will take  care of all of that for you, which is amazing. JASON: And it also -- I can just picture a few  things that have stopped me from doing really intense have animations in the past like  responsive styling for it. And things that, you know, when you're
doing it in JavaScript,  you're like trying to re-implement features of CSS to make sure that it fits within the window, to  make sure that it's visible. To make sure it's the right width, that the aspect ratio is not messed  up. And if you're in CSS, if I'm animating a div, and I know that the thing inside of that div is  sized properly, then I can -- I can just animate that thing and know that my CSS is going to apply  to. And like I'm not trying to take my CSS out of the style sheet and into
the animation tools like  custom styling thing that I hope works the same way. And, you know -- and it really just -- it  feels like kind of coming home as a -- as somebody who is building a lot of in my case very silly,  but still fairly ambitious. Like I want to make something fun happen when you see this website.  And I love that you can do so much more of this just using web standards. And I'm not loading.  I love GSAP, no shade on it at all. But it's nice they only these GSAP for my really
advanced  ideas, as opposed to reaching for it when I want to do anything at all. Which sometimes feels  a little heavy when I'm like, I wanted this to move from here to here when you scroll down the  page. And I don't want to load GSAP to do that. BRAMUS: Yeah. Because it taps into CSS. You  can use -- it's just a bunch of properties and values that you set. But you can integrate into  prefers reduce motion media query. Into another media query that says, hey, if the screen  is very narrow, an
imated in a different way, it's all just in CSS that you can do it.  Do note, I'm focusing on the CSS part here. JASON: Sure. BRAMUS: If you want, you can have it integrated  with web animations API which is the JavaScript way of using the same mechanics. So, you  can do both, but I prefer the CSS way. JASON: Yeah. And I guess it's like another tool  to have in the belt which is there's no better way to be than just prepared, right? If you know how  all these things work you can choose the solut
ion that's going to get what you want in the least  amount of jank for the users, the least amount of ongoing effort. A good thing to learn and  understand because, you know, especially these days, everything is expecting websites to do a  lot. Where our expectations are getting really high for what a good website is. And what a  good website feels like. So, these sorts of times being built into the browser. That's a big  opportunity for us to level up without having to take that out of the perf
ormance budget or take  that out of the -- the experience of users on less-performant devices. Because as you said,  it's a progressive enhancement. If they don't have a device that supports these, it really big  deal animations or whatever, we can detect that. We cannot run the animation and just show them a  perfectly reasonably-looking -- like good-looking site that doesn't have stuff flying all over  the screen. I just love that. It is wonderful. BRAMUS: You want to see an example? JASON: Ab
solutely I want to see an example.  All right. Let me -- let me switch us over into the pair programming view here. Let  me get this over here and then I'm gonna move this on to the screen. And there we go!  All right. So, before -- before you start, I'm going to do a quick shoutout to our --  our sponsors and our live captioning. So, we've got White Coat Captioning, Amanda is with  us here today doing the closed captioning for this show. If you want to see is that, just click  that little close
d caption button that's right down there. And that's made possible through  our sponsors, Netlify and Vets Who Code, both kicking in to make this show more accessible to  more people which I very much appreciate. We are talking to Bramus. What's the right place to send  people if I want to point them to you on the web? BRAMUS: Twitter or X, I should say. Sorry. Bramus  is my username. And also, my website, Bram.us. JASON: What a good website.  That's a good domain. I love that. BRAMUS: Thanks. J
ASON: So, this is you. Let's find  the scroll CSS -- what am I looking for? Is it not scroll behavior... I want... BRAMUS: Well, you want a few properties. But maybe the easiest thing to do is go to  scroll-driven-animations.style. JASON: Scroll-driven-animations.style. BRAMUS: Dot style. And they have like a full  page with everything thereon. If you scroll, you already see scroll-driven animation. Did  you see the mouse move as you scroll down. JASON: Yeah. Look. As I'm moving up and  down, it
moves with me, right? It's not like a trigger once and then it's done. It's very  much a part of the site. And these scrolling -- BRAMUS: And same with the cards,  reveal themselves as you scroll. JASON: I love it. All right. BRAMUS: And so, the basic one that  you want to check out there is the reading progress indicator. I think  that's really good starting example. JASON: Okay. So, you can see up here,  we've got -- as we scroll down the page, it's showing how much of the page is left to rea
d. BRAMUS: Yep. exactly. JASON: Which this was all the rage -- I think I  saw three or four independent JavaScript libraries that got published. Hey, install this package  to get a reading progress indicator at the top of your site. And now we can do this in CSS. And  if I had to guess, I'm gonna take a wild guess, that building this particular interaction  is something like ten lines of CSS. BRAMUS: For the animation part, it's less. You need the positioning part.  But yes. It's only a few line
s of CSS. JASON: Wonderful. BRAMUS: That's the easy one.  Go to the icon switcher at the bottom. Go back to the reading progress. JASON: Oh, switcher icon. BRAMUS: Switcher icon. Click on that one, and  number four. That's the easiest one. Yeah, there's a few ways of approaching  a scroll-driven animation and this is the easy one. And if you  now click on the info icon, you should get like a little explanation  of how is this thing built? Of course -- JASON: Whoa. BRAMUS: You could check it out
with  DevTools, but this is like me writing down, this is how it works. I can walk through it.  But maybe we should use DevTools to inspect it. JASON: I mean, this is great. This is so cool  to see. Just looking at this -- like this is how I expect an animation to work. We scale it  on the X axis. So, left to right, down to zero. And when -- that's when you start. And then when  you're done, it's scaled up to its normal size, which is full width. And this we stick it up  to the top. And left, we
make it 100% wide, give it a height of 1 REM. And look at this.  This is beautiful. We just say "Grow," like use this animation. And we tell it to use the  scroll instead of the regular timer. Like -- BRAMUS: Yeah. JASON: This is a brilliant solution because it  doesn't feel like it changed what I know about CSS. It's something that I could have built  that would have looped as like a growing bar. And then you just change out the timeline.  And suddenly it's a completely different thing. And th
at's such a -- it feels good.  Like you mentioned earlier that the original implementation was like JavaScript being kind  of ported into CSS. This feels like CSS to me. BRAMUS: Yeah, exactly. And it's as you mentioned.  Like you start off with your existing CSS, your existing animation. If you have that  one working and it runs over a certain time. The thing that you need to do is there's  basically two things that you need to do. One is you remove the animation duration or you  replace with th
e value of auto. Which you can see here in the animation shorthand. And then  secondly, you add an animation timeline to it, and from there it will run on an animation  timeline. But, of course, there's a few tweaks that you can do. Like which scroll timeline do  you want? But by default, what the scroll function will do is it will look up the nearest scrolling  parent of the element that you are targeting. So, from the progress element up, it will look  at all the parent elements and the neares
t one has a scroller that will be used to  drive the scrolling. And in this case, it's just a document scrolling because the  progress div is a direct child of the body, and the body is a child of the HTML. You have  your root scroller, your document scroller. JASON: Amazing. Like, yeah. This is  -- it's just so good. This makes me so happy. And then so you implemented  a few different versions of this. BRAMUS: If you go to version 3, for example. JASON: Okay. BRAMUS: Yep. It's the same demo, it
's  the same output. But only the code is a little bit different. And what you see here  is for the animation-timeline, we have passed two arguments in there. Block and nearest. And  block is direction which you want to track. So, it's the block direction which is in our  western world it's just from top to bottom. JASON: Okay. BRAMUS: If you want, you can also go in  line in there so it goes horizontally. JASON: Oh! BRAMUS: So, it's different  axis so you're scrolling horizontally. But now we'r
e scrolling vertically. JASON: Fascinating. BRAMUS: Horizontal and vertical, that's one  of the four keywords you can use for that. And the last keyword is which scroller  you want to track. And by default, it's gonna be the nearest parent. This  is basically the default value here. JASON: Okay. BRAMUS: You can say root or self. And root will always map to the root scroller. If you  have a scroller inside of a scroller, but you still want to scroll -- track  the document, you pass in route. JASO
N: Okay. BRAMUS: And self is track myself.  As I am scrolling, for example, if you want to change the background or  something like that. I hope that was clear. JASON: Yeah. Yeah, yeah. That is clear.  That's -- okay. So, you want to -- do you want to keep looking at demos or do you want  to walk me through building a few of these? BRAMUS: Maybe we can take a look at the  carousel step indicator and then one, and then we can build something, right? JASON: Okay. BRAMUS: So, here I have a carousel
. But  if you scroll through it horizontally, the progress bar will also move. JASON: Okay. BRAMUS: Like I just mentioned, you have the  scroll function. So, in the arguments there, you would pass it inline because it tracks to  inline. The inline axis of the scroller. But I did something else here as well. I gave the scroll  timeline a name. So, that's what you can also do. So, you have this scroll function to say, hey,  create me an anonymous scroll time instance. That's basically that. But if
you want, you can be  very explicit about it and say, hey, this scroller over here. I'm gonna give the scroll timeline  name. Which is dash, dash, and then its name. JASON: Okay. BRAMUS: With the value of inline. And then you  use that name as the animation timeline further down. Instead of the function, you pass in  the name that you have given to the thing. JASON: Got it. Okay. All right. I think -- I  think I understand, and so, this is something different than what you would do, like... it'
s  still scrolling. But it feels like kind of a unique use case here. All right. So, I'm gonna  back out. What else would you like to like at? BRAMUS: And then maybe one with -- let's take the  image effects, the one in the center. That's like a classic one as well. So, and if you hit the  little switch icon again at the bottom right, go to the number two there. Anonymous view  timeline. Yep. This is also a scroll-driven animation. The image is revealing. As  you scroll up, the image is revealin
g itself. But it uses a special type of scroll  timeline. So, by default, a scroll timeline is just tracking a scroll as you scroll from the  top to the bottom, you go from zero to 100%. JASON: Okay. BRAMUS: But this uses a view timeline which  says track this element as it is entering, as it is crossing the scroll port. Which is  like intersection observer if that rings a bell. JASON: It is, yes. And this is huge because I  love intersection observer with my whole heart and I hate -- hate! -- s
etting up intersection  observers. Because I'm always doing it for something simple like this. So, this, replacing  my entire intersection observer setup code, my life just improved in a very tangible way.  This is amazing. I am so blown away by this. I actually didn't -- so, when Una showed me the  site, we looked at it for a minute. I didn't realize I could look at the source code. I  needed to come back and inspect this later, I didn't to want derail the show. I'm really  excited this button
is here where I can look at these and see. This is incredible. I did not know  that Vue was an option. And that is gonna change a lot of how I think about what I can build  on the web. Because I don't have to set up an intersection observer now. I can just run that and  do a bunch of fun things as they scroll into view. BRAMUS: Exactly. JASON: Good stuff. BRAMUS: It's so powerful because  one line of CSS and it works. JASON: Oh, man. This is what I'm talking about  as improvements in the platfor
m. As a developer, I don't want to write arcane code to make the  things in my head a reality. When I was younger, I had a lot of ideas, oh, it would be cool  if this was interactive like this, or this was hooked up to this interaction. I would talk  myself out of it because as I looked into a it, the level of complexity to make that real, it was  just too high. Too many cross-browser things to consider, it was written in JavaScript. I had to  do my styles in JavaScript. Just broken stuff. This
feels janky, I'm just not gonna do it.  Good ideas died because I didn't have the bandwidth or the knowledge to build these very  complicated work arounds. And now the browser is just giving us these tools that let us do this  sort of thing in a way that doesn't require me to have like intense amounts of knowledge about  how each of these things worked under the hood. I just know I want to do a thing, which is a CSS  animation. I know to write those. I want to do this thing in the viewport. And
add one little  thing. I want this to play in response to the user scrolling up and down the page. I want it to  just do that. It feels like a game changer to me. BRAMUS: That's the beauty of CSS being a  decorative language. You're not occupied with all the fine details and all the  little knobs. You're just saying, hey, browser, please try and do this.  It will do it for you. Amazing. JASON: So, so good. Okay. Did you  want to show any of these others? BRAMUS: There's a bunch of them. I  could
talk on hours on all of these. But maybe dive into some code  if you would like to do that. JASON: Okay. Dive into the code. Should we use a CodePen? Should I stand up a  local site? What do you think? BRAMUS: Oh, whatever you want. Maybe CodePen is  the easiest. Then people can check out later. JASON: Okay. CodePen. So, I'm gonna set up a  CodePen. And we're gonna say CSS scroll-driven animations with Bramus. Save that. And... I  think I can -- I always forget how to share these. Here we go. T
his should let anybody  who wants to kind of follow along live as we go. It does not make it collaborative.  So, you'll fork it if you change it. But this will let us get started. And I'm just  gonna drag that JavaScript right out of the way there. Because we're not gonna  need it today, friends. All right. So, what would you like to start with? And I  can give us some elements to start with. BRAMUS: Maybe we should try and  re-create an effect on the list where every list item fades in as it  c
omes into view and fades out as it goes out of view. Because then I can talk to  you about the animation ranges and whatnot. JASON: Let's do that. BRAMUS: Let's have a list. JASON: I will set up a list. And our list  is going to have -- we can set up like a little image. And maybe we won't start  with an image. Maybe we start with like an H2. And we'll say a name. And then we'll  have some kind of a description here. Maybe do some Lorem Ipsum copy pasta. But for  now, just give some space. And t
hen -- BRAMUS: Exactly. Let's copy-paste the thing. JASON: Those. And then I and just very quickly  do like a list style : none. Merge in of zero, padding of zero. And our list items we can -- we  can be like... do you have a very specific way that you write your properties? Like I have  to alphabetize or my brain short circuits. BRAMUS: I try, it's for the first five minutes. But then it all goes out of  control. It's like, hmm... JASON: Just kind of like a very -- a  very simple like rudimenta
ry setup. BRAMUS: Yeah, perfect. That's what we need. JASON: And we'll just -- a  little centering there. Okay. BRAMUS: All right. So, what we basically  want to do, we want to fade in these things as they enter the scroll port.  That's the point that we want to do. JASON: Okay. So, I can set up a frame, and I'll  do opacity zero. To opacity 1. And that's how I would do this. And then if I were to just kind  of set this up I would say like animation, fade, 1 second, linear. All of these to fade
in like  that. And then they're done. Nothing else happens. BRAMUS: All right. JASON: So, to hook this up on scroll... BRAMUS: You remove the duration. JASON: Okay. BRAMUS: So, 1 second, throw it out. And then  set animation-timeline to the value of view, which is the function. And now as you scroll...  you will see that they fade in from the moment that they are -- it starts like when they are  at the very bottom of the scroller. And then by the time they are at the very top, like when  they ha
ve just exited the scroll port, there they are at opacity 10. That's what the view time  does. It creates a range from just underneath to just above. But now we need an extra property. We  want to shrink it down. No, fade in when you are at the bottom. And then you go just at the top.  Like run to there. And for that, I have a little helper website. And it will guide you through it. So, if you open up scroll driven animations.style again, I have a little tool  on there that will help you. JASON:
Okay. BRAMUS: If you scroll down here on this page, yes. And then the view timeline ranges  visualizer. The one on the right. JASON: Okay. BRAMUS: That's the one that you need. JASON: That's handy. BRAMUS: And if you click something, the  click to start will go away. It doesn't scroll. You have to drag it. Zero  to 100%. That is the default range. JASON: Oh. BRAMUS: That is the full range. JASON: Got it, okay. BRAMUS: And these things have a name. So, you  have several ranges. You can change it
with the drop down button there at the top right that  says "Cover." It you change it to contain, for example. And you can see -- and then the bottom  one, set it to mirror. That's gonna be easiest. JASON: Oh, mirrored, okay. BRAMUS: Yep. This is the contained  range. It runs from zero to 100%. When the item is sitting at the bottom  edge until it goes to the top edge. JASON: Got it. BRAMUS: And also the other range, which is entry.  If you check that one. And you can guess what that one does.
It runs the animation from zero to 100%  when it is entering scroll port. So, that's -- JASON: Got it. BRAMUS: -- the range that we want  to target. We don't want the full range of cover. We only want this entry range. JASON: Got it. BRAMUS: And of course you have exit  which is like the one at the top. JASON: Okay. So, then for me  that means in here, I want... BRAMUS: A new property animation. JASON: Animation range. Do I just like? BRAMUS: entry, and that's it. JASON: Okay. BRAMUS: And now ev
ery itself will have  a view timeline. It will create a view timeline that tracks it. It will run the fade  animation from the entry. It's from just below the scroll port to the view. And you  can tweak the numbers if you want. JASON: We will make this a little  more obvious what's going on by inverting the colors here. I think that will help. BRAMUS: Yeah. JASON: Because then you can  kind of see them coming in. BRAMUS: Yeah. JASON: Like that's cool. We want to do a little  bit more to make it
a bit more obvious when the colors aren't inverted like this. Because it's  kind of -- it's very subtle right now. Which is -- I mean, sometimes that's actually like  great. You want it to be just subtle enough that you can feel that something is happening.  But it doesn't draw a lot of attention to itself. BRAMUS: What I like to do here is that the from  position. So, the starting position. I want to translate the thing a little bit down so that when  it enters, it's like -- moves up a little b
it. JASON: Okay. And to do that, I translate  why and you want to translate it down. BRAMUS: Translate why won't work. That  property doesn't exist. Yet. We're talking about it. But you want translate  zero percent on the X axis and then, for example, 50% of to 20% on the  Y axis. To push a little bit down. JASON: Oh! BRAMUS: It goes up. One tip, by the  way. We didn't repeat translate in the two keyframe. Because the default  for translate is don't translate. JASON: Right. BRAMUS: And the same
for the  default value for opacity. It's one. We can just remove the two block there. JASON: Oh, interesting. BRAMUS: So, if you throw it  away, it will still work. JASON: Cool. I did not know that. BRAMUS: So, that's the entry range. If you want,  you can tweak the numbers. Because now the element needs to be fully in view. Maybe you don't want  that. So, you can also tweak the numbers. So, you can -- instead of just entry, you can  say, entry, space, zero percent. Space, entry, 50%, for exampl
e. Entry, 50%. And then  the animation will run from when the element is just outside the scroll port up to the  point where it's halfway in the scroll port. JASON: Oh, okay. BRAMUS: So, it runs a little bit faster.  If you want to set it to 150%, for example, it also works. So, then it lags a little bit. JASON: Oh, see, and that's great.  Because now -- now it feels snappy and is like a little more visible what's going on. BRAMUS: What I really like to do,  by the way, is these percentages, the
y like depend on the size of the element  itself. So, if you have a shorter element, it's gonna like -- the animations won't want to  go over the same distance. So, what I like to do is I take entry 100% which is like entirely in  view. But I wrap the 100% in a calc function. JASON: Oh, I see! BRAMUS: Calc 100%, plus 20 pixels, for example. JASON: Got it, yeah. BRAMUS: Or like zero percent minus 150 pixels. You  can do calculations in there. It's really cool. JASON: Because then if we take one o
f these...  let's take probably one toward the bottom so that we can see the difference and make this  a lot longer. Then... instead of feeling... BRAMUS: Now it takes longer. What  we can do is the calc one. Set it to zero percent minus 200 pixels, for  example. Or maybe plus 200 pixels. Then it's always a fixed distance  of 200 pixels that it will move. JASON: Got it. Okay. So, in -- and then it's done,  even though we're not in view -- oh, yeah. Okay. BRAMUS: That goes over the same distance.
JASON: Great. BRAMUS: Yep. JASON: So, lots of ways that you can tweak this  to make it suit your specific interaction goals. BRAMUS: You can change the ranges, zero percent  to 50%. That way it will animate from just under the scroll port to just under the scroll port.  And you can calc -- it has so many options here. JASON: Oh, yeah. BRAMUS: The very center. JASON: That's cool. I mean, this is great! And  like, you know, this is one of those things that it just -- it's subtle. It feels good. I
t makes  you want to kind of keep scrolling a little bit. And so, obviously, that means it needs to be used  with a little bit of care. Because if everything on the side is doing this, it's gonna be real  world and distracting. But used tastefully, this is such a nice power up to a website. It  takes something like moving between your blog list and gives it a tiny bit of motion, right? And that  tiny bit of motion can have a big impact, I think. BRAMUS: This demo right here, we have it. We can d
o the fade in. If you  want to do the fade out, it's really easy. JASON: Okay. Let's do it. BRAMUS: We can do that in like 5  minutes. So, when you set a value to a property to have multiple values,  you can just come and separate them. JASON: Right. BRAMUS: So, for example, with  animation, you can do fade linear, comma. And then fade out linear.  And then with animation range, you can set a second value. So, maybe just  for convenience, set it to entry, comma exit. JASON: Okay. BRAMUS: So, the
one value needs  to be. The first value is entry, and then the second one is exit.  But of course if you can -- JASON: Oh, I gotcha. BRAMUS: The long version.  Yeah, entry, comma, exit. JASON: Okay. BRAMUS: And then we need to create  the fade out keyframes, of course. JASON: All right. So, copy this. And two, right? BRAMUS: That's two. And then the  translate needs to be to make the number negative. Exactly that's it. And it -- JASON: I screwed up because  I didn't change the name. BRAMUS: And
I don't think it entirely works,  it does because of the overlap. Sometimes you need to play a little bit with the film  mode. What I do is the entry animation, I set that one to backwards. So,  fade linear, and just backwards as a film mode. And then the end animation, the  exit animation, I set that one to forwards. JASON: Okay. And I don't --  so, I've seen that before. But I don't actually know what it does.  What is the film mode in animation? BRAMUS: The film mode in animation determines
what  should happen when the animation not running. What part of the keyframes do you want to show? The  before part at zero percent or the 100% part, the forwards one, or do you want so set  both? For example, if you're at the start, set the first frame, and if you're at the  end, that settle both. That's forwards, backwards and both. And maybe a forward  value, but I only use these three. JASON: Okay. Cool. So, this, then, is basically  what we're saying -- and the reason that you do this -- i
s that when you've got these two  animations, if my view port was shorter, they might collide. We would still be  animating in at the same time as it needed to start animating out. And  by setting backwards and forwards, we bring them closer together so that  they look smoother as they move through? BRAMUS: You're basically doing the opposite.  You're saying when they are at the outer edges, the entry one, that one goes backwards. It remains  at opacity zero when it's way outside of the view. JA
SON: Oh, okay. BRAMUS: Yeah. And here it doesn't like really  matter because the end frame of the fade one is the same as the starting one of the fade out  one which is at opacity zero translates as zero. JASON: Right, right. BRAMUS: But if you have other types of animations, I like to do this one. The entry one to  backwards and the exit one to forwards. JASON: That makes sense. Backwards means it  goes back to the from. And forwards means it goes forward to the two. That makes sense. Got to  w
rap my brain around this. Okay. Cool so, this is very cool. What -- what else should we show? Like  should I... should I wrap things in -- in scroll dives and like make a pile of these? Or do we want  to create separate pins? Or what do you think? BRAMUS: Maybe create separate pins, yeah. JASON: Okay. We can do that. BRAMUS: Or maybe we should go into a little debug  their I built. Because that one is really healthy. JASON: Okay. BRAMUS: Like in the ranges in the beginning, I  was also very conf
used. When I read the spec and when we were refining the spec, I was like, what  do these ranges mean? I don't understand. So, I helped -- the tool that I built  already gives you a little hint at that. But I built an extension to DevTools  that lets you debug it in DevTools itself. JASON: Okay, I do... BRAMUS: Back to the home page. At  the top, there's a bunch of links. JASON: Here? BRAMUS: One is to see the demo, learn the  syntax, which is an article. And then get the extension. Yep. And the
n you have a  link to the scroll debugger extension. JASON: Got it, okay. BRAMUS: I'm not sure -- it should. JASON: Yeah, I haven't had too much of a  trouble with it. But I guess we'll find out. Yeah. And in chat, ayush was  sharing this. You have got people. BRAMUS: One note, the debugger doesn't work in  iFrames. And everything in CodePen is an iFrame. JASON: Okay. BRAMUS: Open up your pen in debug  mode and then you can inspect it. JASON: To do that... BRAMUS: That's a layout icon at the top
. Yeah, that one. And then debug view.  Then you have the standalone page. JASON: Okay. BRAMUS: And you can inspect on one, yep. So, you  have -- you grab the -- yeah. And then at the top, you have this tab bar, styles, computed layout,  eventlisteners, it had the arrow. There's a new one in there. That says scroll-driven animations.  And now if you scroll the page, you can see what's happening. So, maybe grab like the fifth  line on the page. That's gonna be interesting. JASON: Okay. BRAMUS: So
, now you see what's happening.  You see a visualization of the scroll port. And then you see a visualization  of the tract box and actually -- JASON: Oh, that's cool... BRAMUS: And the actual animations. JASON: And then I can choose the animation. BRAMUS: Yep. JASON: That's very cool. BRAMUS: Now what's also possible is if you hit the  add values there at the bottom, the bottom right. JASON: Here? BRAMUS: Yep. Maybe make it a little  bit bigger so that you can see it more clearly. Then it also
draws some  to and from boxes. For the ranges. So, these starting positions. And you can also change  the values here at the bottom. But this is like straight into DevTools. And it will also sync  back to the actual element on the page. So, if you change, for example, the percentages,  exit zero percent, if you change that to 50%. JASON: 50%. BRAMUS: And then you need to blur it  -- then the box gets updated and then the animation will also run at a different point. JASON: And there it goes. So,
the  rest of them are still standard. And this one... this is getting real  weird because we messed with it. BRAMUS: It's for 0.0. If you  find a bug, please file one. JASON: I think I just gave it really  bizarre settings. Let's see... zero... BRAMUS: You need to blur the text  field. Okay. You did that. Yeah. JASON: Now it looks like I just  broke it. It's playing the other one. Interesting. Still... a very, like -- BRAMUS: It broke. JASON: What a handy tool to be able to see  this stuff in a
ction. Like this alone kind of pays -- pays for the price of admission  there. Because for me, like a lot of times I know what I'm -- I know what I'm trying to do.  And I know what the value should be. But I can't always visually map the number on the screen  to the behavior that's actually happening. So, having something that can do this for us that  just shows us, this is the animation you set. Here is where it fires. Oh. I want that to  fire later so I can tweak the numbers to move it up or d
own or whatever it is to get  what I want. Solid stuff that's really good. BRAMUS: And top right, you can see  the numbers. You can see the number going up from zero to one. Which is the  full range. But also just limited to the effect. And then also the actual pixel  offset value that you get there. Yeah. JASON: Cool. This is great. So, this is like  the actual element. How much of that view is happening. So, you can see it goes from  zero when it's off to one. And then this one is the full pag
e scroll. So, veer at  the very top, one at the very bottom... BRAMUS: It's the full range. So, when  the item is sitting underneath the scroller and sitting on top of the  scroller, that is the full range. JASON: And then this here is the pixel offset.  So, how far down we've scrolled, right? BRAMUS: Yep. Exactly. JASON: Very cool. I mean, these  -- that is also -- this is great. This is like a really handy extension to have. BRAMUS: That's why I built it. Because I  also needed this for myself
. I wanted -- I want to do stuff, but I don't know  where the boxes are. Help me out. So, I built this to help me. And it  can also help you. So, win-win. JASON: Yeah, this is great. So, let's  see... I have... where -- here we go. I'm just gonna drop a link. I already shared  it. But if I share it, it goes into a channel in my Discord so that everybody can find it  later. This is great. Like I -- I love -- I love what we're seeing here. We've got about 30  minutes left. And I've seen you do som
e stuff that absolutely melted my brain. That didn't  look like a scroll-driven animation. Do we have time to put together a rough demo of something  like that in the 30 minutes we have remaining? BRAMUS: Yes. Let's go for it. Which  demo are you talking about, I'm curious? JASON: You did -- scroll-driven animations.style,  this one was really, really cool. And then this one was very, very cool. This also is very cool.  So, this one I imagine is probably a little more than -- I don't have the as
sets for this one.  But something like this, or something like this... are both extremely cool. This might  be the most like tractable in 30 minutes. BRAMUS: Yeah I was gonna say, the cover card,  we see that on many websites. And with CSS, we can mimic that and achieve exactly  the same. This is a really good one. JASON: The landscape and text one. You're talking about the cover card here? Let's do  it. I'm going to create a new pen. BRAMUS: Yep. JASON: And scroll-driven animations with  Bramus
. Part 2. Okay. And then I'm gonna set up a -- should it be a separate element?  Like if I'm -- if I was gonna mark this up, I would probably end up with like my -- my article  element. And then I would have for that header, I would probably just use a header element.  And then I would have a -- like a section for the article copy. Is that gonna be compatible  with the way that you would build this? Or do you want to tweak that? No, this is good?  Okay. So, I'll have an H1 and we'll call this gr
eat article. Okay. I'm gonna save  this. And then I will share the link for everybody. If you want to follow along. And  then inside I'm gonna go get some Lorem Ipsum. BRAMUS: In CodePen, if you  hit Ipsum and then load tab, it will generate a Lorem Ipsum  for you. Or maybe Lorem tab? JASON: Oh, look that the! That's handy. Okay. BRAMUS: But it only gives you  like one paragraph. So, yeah. Maybe Lipsum.com is handier  because it gives the HTML elements. JASON: I thought it did. I thought this on
e gave  you all of the markup. But it doesn't... whatever. Edit as HTML. And then I'm gonna go grab all  of this. And drop it in here. Okay. Do a little format so that it doesn't hurt my eyeballs. And  then -- good. All right. So, then the other piece that we need is an image of some sort. So, I'll  just remember to unsplash. And I am gonna make this article about donuts. So, we'll just grab...  a full screen donut image. And come back in here. And let's see... do you -- should I set it up  as a
-- like a background image on the header? BRAMUS: Yeah, set it as a  background on the header element. JASON: Okay. BRAMUS: So, that way you can do background  cover. Like just to stretch it out a little bit. JASON: Okay. And we'll do background,  size. Cover. And then we'll set the height to be -- started at 100,  right? Looks like I also need to reset the body here. And I think that  might be my -- let's see. So, actually, why don't we just have this on a display flex.  And then -- is there -
- I feel like at some point I got shown a shortcut for align -- align  items and justify content as like one property? BRAMUS: Replace content. JASON: Place content? BRAMUS: Yeah. Center. Maybe try display grid? Or  place content or place items? It's one of the -- JASON: Play grid, place content center. Gave  us exactly what I wanted. And I am so happy. This is -- this is also magical. So, then let's  see... so, we've got -- that's kind of all we need for the markup. We've got our header and  ou
r piece, I think. And then if I take my... I don't know. We can just do something  like -- background size, background... BRAMUS: What I also did is background position  50%. Or center. To make sure it's lined up. JASON: There it is. There's our thing. Okay.  So, then we have something like that. I'm gonna set the H1 to have just a little bit  of background color so that... say, like, HSL... we'll go with -- zero. Separation  is gonna be zero. We'll just make it black. Zero... and say 25? Yeah.
K. Then we can make  it width 100%. That didn't do what I wanted. BRAMUS: There it is. W. JASON: And padding, I don't know, 2rem. BRAMUS: What chart with the W by the  way, if you have a system with classic scroll bars. We have the overlay scroll  bars that go on top. With the classic, they don't take the size into account. You can  see that in Firefox. That's a bit of a pity. JASON: There's. That's probably legible  enough. And yeah. Let's roll from there. BRAMUS: All right. You want  me to wal
k you through it or you're gonna take a guess what you want to do? JASON: So, I think -- yeah. I mean, what  I would do from here is after making this breathe a little bit... and then the width of...  90%. So, what I think I would want is -- you know what? To be completely honest, I actually  don't know. I don't know how I would do this. BRAMUS: All right. I'll drop you some clues,  right? Let's work on this together. Right now the header is 100vh in height. But at  the very end, we only want it
to be 10vh. JASON: Okay. BRAMUS: So, that should be part of our keyframes  that you want to animate to a height of 10vh. JASON: Okay. So, we want to  go to height of 10, right? BRAMUS: Yep. JASON: And then if I set my animation,  it will be header scroll linear. And animation timeline I'm guessing is gonna be  "Scroll." So, then... oh, yep. That goes bad. BRAMUS: Yeah. So, I run into this as well. So, the problem is that when you are calculating  a scroll timeline, you are calculating against t
otal scrolling distance that you have.  But if you are now shrinking the header, your total scroll distance is also shrinking. So,  all of a sudden it goes like, boop! And it's -- JASON: Oh! Yeah. BRAMUS: So, the work around is we need to make  sure that this header is sticky. But the problem with sticky -- so, my guess would be oh, just  use position sticky on it. And then we'll do it. The problem with sticky is the thing  never leaves the actual scroll port. So, my solution they use instead of
"Sticky"  is I make the header position fixed. So, it always stays in view and  it's against the position view port. JASON: Okay. Position fixed. BRAMUS: Right. JASON: For a second... BRAMUS: Yes, so -- JASON: I can't tell if that like opted weird or  if that was glitch. I'm gonna save it. I'm gonna reload it. Autosave is enabled, I'm gonna reload  it, and I'm going to scroll. I can not scroll. BRAMUS: The problem with position fix, you take  it out of flow and you just drop it on top. JASON: O
h, right. BRAMUS: But all the text that was  underneath has shifted up. So, you need to counteract that. And on the  text, you need to say, well, your margin top is 100vh. Because the text is shifted  up, you need to push it back down by 100vh. JASON: Oh, okay. Okay. BRAMUS: And now hopefully  you should be able to scroll. JASON: Okay. I can scroll. But I broke  something... did I break something or is my Internet trying to like short circuit on me? BRAMUS: I could still see and hear you. JASON:
Yeah. Okay. Hold on. I'm just  gonna reload again and see if maybe... BRAMUS: You could always right  click and inspect it, right? JASON: Yeah. BRAMUS: Or maybe top zero to make  sure that it's there somewhere. JASON: Yeah... here is my header. It is missing. BRAMUS: So, if you set it to top zero. JASON: Okay. All right, all right, all right. BRAMUS: maybe we should start off  and just remove the animation, for example. To make sure  that the header is there. JASON: Okay. No. You should be gone
now. BRAMUS: Okay. Yeah. JASON: Okay. So, the cover is there. BRAMUS: All right. Now you've put back the  animation. The view is reloading. And yes. It is scrolling. So, right now you see the header is  actually shrinking from the full size to 10vh. But it's not really synced. And the problem is that  by default, a scroll animation runs if you scroll from the very top of the scroller to the very  bottom of the scroll. But we don't want that. We want like to shorten the range because the header 
should shrink a little bit faster. And that's -- JASON: Okay. BRAMUS: -- where the animation range comes  into play. Like with the entry timeline, we have the cover and whatnot. Far scroll  timeline, we can just set it to some actual values. And for this one, first set the animation  range to entry. To just 0vh space at 100vh. JASON: Okay. And I just added more text to  demonstrate the problem with this. Because with a shorter page, it's no problem. It just  doesn't scroll at the right height.
But with a longer page, look at this, it's just broken. Like  my text is disappearing under the header. So, this is -- this is the sort of thing  that we like -- we have to fix this. So, you said animation timeline, I  need to set the animation range. BRAMUS: Animation range, yep. JASON: And you said? BRAMUS: Zero vh, space, 100vh. That  way you're saying, like, hey, header, when you're scrolling the page for 100vh, shrink  to your 10%. Yeah. This is a very good example. You have done that. Now
it switches to this.  There is because of the film mode. So, we need to set the film mode to forward so that when the  animation is done, it keeps that very last frame. JASON: Makes sense. Okay. Oh, wait. Did it actually reload? Is it  four words with an S? Or forward? BRAMUS: Forward. Yep. JASON: There it is. Oh, my goodness. BRAMUS: Okay. Oh! JASON: What is happening? BRAMUS: It was there. It wasn't there. JASON: It dumped my change. I think either  my connection or CodePen is having a moment.
Because I'm -- it's like not loading as fast as  I'm used to. Okay. So, that's doing what I want. BRAMUS: But you can see it's not perfect. Right? JASON: Yeah. BRAMUS: Right. So, I've set like  -- this was my first idea as well. I want to animate a header. If you  go from zero to 100vh. But actually, we need to subtract the remaining height. So,  we want to animate it not from zero to 100vh, but from zero to 90vh. So, the remainder --  the remainder of the finishing height. And if you set it to
90vh, it should work.  Like the text now always stays -- yep. JASON: Yeah... BRAMUS: You could give it a little  padding. The little div to not have it stick to the header. But this  is a demo. There you have it. JASON: That's fantastic. And then if we  wanted to make this more like legible, we would probably go with something -- something  like that. And look -- look at our -- like... this is is the sort of thing that we used to  spend hours in tutorials trying to get right. BRAMUS: Yep! JASON
: And to make it not feel weird and  not bounce our text around. As somebody who is attempting to build good experiences  like this, I -- there were like think pieces all back when Medium was like the way that we  talked about web Dev for a while there. There were all these great think pieces because why you  should never do this because it introduced jank and weirdness and all these problems. And now  here it is, non-janky, progressively enhanced. BRAMUS: There's little notes to make with  this
one. This one is gonna be janky because we are animating the height. And animating the  height doesn't work on the compositor. You have to transfer opacity, those run on the compositor.  Width, height, background color don't. Thankfully, though, we have very clever engineers on our  time. I think about two months ago, they said, we should fix that. They are working to make  this work in the future so you as an author don't have to think about, does this run  on the compositor or not? We are goi
ng to tackle the main cases. If you want to animate a  background color, for example. That should run the compositor. And width and height, that should  run on the compositor because we often do that. JASON: Right. I mean, this is fantastic. And some  good notes in the chat about like making sure that we're respecting preferred reduce motion. Here  is maybe a question. Because not every -- like prefers reduced motion is not prefers no motion.  We're just trying not to trigger vestibular disorder
s and stuff. Right? So, when -- where  do you draw the line? Like for me in my head, the things that I immediately think about  are like no strobing, nothing like whooshing around the screen. But something like this  -- is this -- is this something that you could keep as reduced motion? Or like where  would you -- where would you draw the line? BRAMUS: Of course, as with everything on  the Internet, it depends is the answer. JASON: Sure. BRAMUS: But with this, I am perfectly fine with  this. Bec
ause there is still this direct link between you moving the page and the thing  shrinking. So, it's like a one-on-one type of thing right here. Whereas if you go to scroll  reduce animations, the cards that fade in and use a view timeline. Like at the home page -- yeah.  Like these little cards here at the bottom. Like this is a bit weird, right? Because there's some  clipping going on there. And there's a little translation going on there as well. And people  will get nauseous of this because i
t's like a lot of movement going on. So, this here on the  home page, I wouldn't do that. Prefers reduced motion on. The shrinking header, I think, I  think that's fine. Of course, there will be people that say, I'm getting nauseous off this.  But I think that's one of the safer ones. Yeah. JASON: And I guess the nice thing about  something like this is that you can control it. Like if you need to go slower on this,  you have the control for how fast it goes. BRAMUS: Yep. JASON: Which is kind of
a nice bonus  as scroll driven animations go. BRAMUS: And that's why this  is scroll-driven animations. Because there is a direct link between  you scrolling and the animations going backwards and forwards. This is  not scroll-triggered animations. JASON: Right. BRAMUS: Scroll-triggered animations, you  are scrolling and at the certain scroll set, the animation will run on the document  timeline, its own time. And you lose control as the user. Because if you stop  scrolling, the animation is go
nna run. JASON: Right. Yeah. I mean, this  is some extremely cool stuff. So, we probably -- I mean, actually we might  have time to do one more demo if you want to. BRAMUS: You said 30 minutes and we did it in 10. JASON: Yeah. So, we've got -- BRAMUS: That's the cool thing about this API.  It's really easy. If you know animations -- JASON: Yes. BRAMUS: The duration, add an animation  timeline to it and you know how to do it. JASON: So, I would like -- if you are okay with  doing one more. I want
to know how you got a scrolling session to move the opposite direction.  So, I'm gonna -- I'm gonna pop open one more pen. BRAMUS: For this one we might need half  an hour. But we'll see how far we get. JASON: Oh, really. BRAMUS: No worries. JASON: If we can't get there, we'll  just go look at the demo. With Bramus, part 3. Save. I'll grab the link. Maybe  I'll grab the link. Icon. Here we go. Link. Shared. Here we go. And I'm going to create  we'll say a main and inside of this main, I'm gonna
have three sections. Put up one  of them to start. Let's see... do I still have... that image on here. So, I'm just gonna  probably run the same image to say us from having to go hunt for them. If we get way ahead of  ourselves and are done faster, we can get more. BRAMUS: I like that you're  putting up an alt in there. JASON: I -- I've just made it a  habit. Like I don't create image tags without alts. Because if I  don't do it now, I will forget. BRAMUS: One tip with that, also set width  and
height attributes. Because browsers use it to pre-reserve some space for the image  while it's still loading so you don't get like a layout shift. But for this demo,  it's fine. You don't need to change it. JASON: Actually, it's a good point. These  are also huge images. Why don't I change this over to be like 600 -- this is the  imgix API. So, we can just set it to a nice resolution. And then we'll go width of 600...  and height of say 400. And now we've got nice, accessible images that are no
t gonna  have weird jank when they load. BRAMUS: Yep. JASON: So, I've got... one, two, three of these. I'm gonna set up main to  have a display of grid. We'll do grid -- BRAMUS: Yep. JASON: Template columns. And repeat three 1fr.  I'll set the section is kind of fine. But we'll probably need that in a minute. So, we'll set  the image to have a width of -- we'll go 2x density. One of those. And then we'll set the  aspect ratio to be -- what is that? Three... BRAMUS: You can just type in the numbe
rs.  Or you can also do height also. And then it should automatically adjust the height  based on the width and height attributes. JASON: Okay. So, we got those. That should get  them all to sit nicely together. I am happy. So, then we've got some scrolling to do here. And  then I guess we can just set like maybe -- oh, no. We don't need that. The sections we would  want to be like display flex maybe with a gap of 1rem and a flex direction of column.  And that way they'll kind of look like a nic
e scrolling bit. A little bit more spaced  out so we got a bit more to scroll. And now, please, I would like to see how  to -- how to get this to work. BRAMUS: All right. So, the trick that I did --  this is based on a demo from code drops. They built it with JavaScript. And it was like,  this looks like something that scroll-driven animation can do so I went for it. The trick  is the center -- all three columns start at the top and bleed out the page to the very  bottom. The trick is that you w
ant to take like the first and the third column and  shift these 100% up so that they sit like at the bottom edge of the -- of the columns  or what's the name? Of the main element. So, first thing that I did is on the columns almost,  like on the main element that you have there... JASON: Okay. BRAMUS: I set overflow Y to hidden. Because we are gonna shift something up and they  should be hidden by default. Yeah. JASON: Okay. So, then -- BRAMUS: And then -- uh-huh. JASON: Do an Nth child of one.
And  Nth child -- you probably just set this to be like odd or something. But  instead, we'll do it like this. And you wanted to translate as nothing to  the left and right. And minus 100? BRAMUS: Yeah. So, if you minus 100,  they are moved out. But the problem is that now they are moved by is00%. So,  they are like way out of the screen. So, you need to calculate a little bit and you need to  say, calc minus 100%, but plus 100vh. Because you want your bottom port -- your bottom port to sit  at
the end edge of the scroller. So, right now -- JASON: Okay. BRAMUS: In the good starting positions, right?  So, the middle column is still at its position. And the first and the third one are sitting at the  bottom edge. That's like the start thing that we want to have. While you're at it, by the way, also  the column, the flex direction of column reverse on to those alt children. Because you want their  images to also be flipped. Right now we have the same images so it doesn't really matter. B
ut  yeah. So, it's column-reverse that you need. JASON: Oh, column-reverse. BRAMUS: And then the first  item will be like the last one. JASON: Okay. Got it. Okay. BRAMUS: That's the basic setup. We have moved  them on to their right positions. Now we need to animate them. On these odd children, you are going  to set animation and link it up to some keyframes. JASON: Okay. So, we'll do one of these.  I'm gonna set the animation to scroller, Lin year. And then animation timeline -- BRAMUS: Just sc
roll because  we're taking the scroller. Yep. JASON: Okay. And I want this to just go to -- BRAMUS: Yeah. And now we need to transform the  elements again. So, as we are scrolling down the page, the elements also need to move. You could  think about this like for half an hour and not find it. What I always do there is I'll make a  little drawing and I like draw it out on a piece of paper. And the final translate value that  I need to get is calc 100% minus 100vh. So, we're basically inverting bo
th of  those numbers that we previously had. JASON: Okay. And I have missed  a step. What is my step? BRAMUS: Keyframes, animation linear...  yes, animation timeline... yes. JASON: Translate, translate, translate. BRAMUS: Let me check what I had  here. And then my columns... JASON: Animation scroller linear.  Animation timeline. I don't need to mess with the range, right? Like the... BRAMUS: No. Because you want to scroll from the  very top of the page to the very bottom. So, if -- oh, maybe on
the columns, set... I'm checking what  I have here. I was gonna say position relative, but that one -- if I toggle it on or off  in my code, it doesn't make a difference. JASON: Okay. So, something I'm doing... let's  see... anybody spot the typo? So, translate... BRAMUS: A trans-- oh, no. It's written  correctly a translate -- no. The direction is correct. I was gonna say X and  Y are flipped. But that's not it. JASON: Column reverse... okay. So, that means I am... what if I just make this... 
let's try just turning this off and we'll... BRAMUS: Yep. JASON: Maybe my -- BRAMUS: So, now you see -- JASON: That's it. It's doing the thing.  Okay. So, that should be... that should be working. And for some reason, it's not. Did  I capture it in this of my grid or something? In a way that would cause it to break  with the overflow hidden or anything? BRAMUS: I am trying some things out here  locally. Hm. Reverse translate, animation scroll, linear. Yeah. That all looks good. Does the  animati
on short hand only allow more values is the question? It allows more values. But  not the timeline. That's why we need to do it apart. But if you removed the overflow Y on  the main. Just to test something out. So, now -- JASON: There it is. BRAMUS: It's doing stuff. And is it okay? JASON: It's mostly okay. It's a little janky. So, it would need some tweaking for sure. But we are  getting the effect which is pretty dang cool. BRAMUS: Yeah. So, the problem with overflow Y  hidden. Now I'm startin
g to doubt why my demo works because it has it in there. Is that you  create a scroller that's just not scrollable. So, if you -- ah! I know. I know. So, the problem  with overflow Y is that you create a scroller that is not scrollable. If you use the scroll  function, it will find the nearest scroller. So, it will find -- the sections will find the  main element which has overflow Y set to hidden. And use that as its scroller. So,  if you put back the overflow Y on the main, that's step one. No
w the scroll element will  find that element as a scroller. But we don't want it. We want to track the root scroller. So,  in scroll, set it to root. And now you have it. JASON: And now we get it. Look at it go. BRAMUS: Default, it will find the nearest  scroller and we want the root scroller. JASON: Beautiful. BRAMUS: The demo there. JASON: And right in the nick of time  because we just ran out of it. Bramus, this was amazing. So much fun. I'm blown away  by how much this open up for us. This i
s a very, very powerful API with so many cool things.  My brain is overflowing with stuff we can build here. So, if folks want to see  more, we've shared the scroll-driven animation site. Is there anywhere else  you want people to go to dig deeper? BRAMUS: On my blog I have a few extra  articles that paint outside of the lines what scroll-driven animations  can do. Scroll down, for example, you can see my previous post. You can use  scroll-driven animations to detect a scroll or not. Which is a
convenient -- unstandardized  use of scroll-driven animations. But you can do it. And if you scroll even more down,  you can use scroll-driven animations to mimic a snapped selector. So, down,  down, down. Where is it? Yeah, here. JASON: Oh! BRAMUS: You can use scroll-driven animations to  apply styling to an element that was snapped. I think that's pretty crazy. As well as like an  un-convenient use -- normal use -- not normal use -- of this API. Speaking of special uses of  this API, Kitsu.dev
, run by -- so, it's k-i-z-u. JASON: Oh. BRAMUS: Yeah. And then Roman Komarov  has their fit to width text that also has scroll-driven animation. He has  a piece of text that adjusts itself to the available size. That's done  using a scroll-driven animation. JASON: Oh! That's super-cool. BRAMUS: I would recommend people to  check out all the articles that Roman has written.Er in so good. It's amazing stuff. JASON: Very cool, with that, we are out of  time, one more shoutout to Amanda and White C
oat Captioning to doing the closed captions  today, Netlify and Vets Who Code for making this accessible. And we are going to do backend  stuff. You want to learn to build an API, with rate limits. James Perkins is going to  talk about that. And using React 3 fiber, I don't know how it works. It's gonna be  wild. That one's at a special time because Michael is in Australia and I didn't want  him to get up at 3:00 in the morning. Rich Harris is coming back. We are going to look  at Svelte 5 and r
uins. And Andrew, email and JSX. Excited about that. Mark your calendar,  join the Discord, get on the email newsletter, whatever the right thing is for you so that you  can follow along and make sure you don't miss any of these. I'm going find somebody to raid. Thank  you for hanging out we will see you next time.

Comments