The full video and many others like it are all available as part of our Frontend Masters subscription.

Rachel Nabors

Rachel Nabors is a CSS animations fanatic and award-winning cartoonist. A regular conference speaker, she ignites new technology with her experience in visual storytelling.

Rachel Nabors

Award Winning Cartoonist

Animation stacking has it drawbacks. Individual segments cannot be looped and only one timing function can be applied. For more complex sequencing, Rachel recommends using the JavaScript animation API. The API includes events like animationstart, animationend, and animationiteration. These events can be used to trigger, modify, or sequence additional animations.

Get Unlimited Access Now

Rachel Nabors: So there's a downside stacking I mean it can be a little tough. If you have four or five different animations on one element. Honestly though, I don't know what you'd be doing to get to that level but okay, let's say, you are an animation maniac maybe you're doing some really intense bouncing.

And instead of using key frames, you've decided that you need all these bounces to have their own different kinds of individual key frames, and you want to call them with an animation stack. There is, well in addition to needing some serious Sass mixins to calculate those durations. Watch what happens when I'm using stacked animations with touch on my own site.

Once again, I'm using my own site so if I embarrass anyone it's me. Zooming in and zooming out. Zooming in, zooming out, pinching getting out of the context now watch her eyeballs are going to disappear.
Rachel Nabors: They're gone and then suddenly she's got the new facial expression. What went wrong there?

Obviously, some things were out of sync, I can't tell you exactly what happened there because I don't have I don't have the stats from safaris CPU. But I can tell you a little bit about what might be happening there. CSS animations and transitions, they run on the system's clock and if the main thread is crowded so much.

So that it takes the browser a long time to get back to it or if it's confused about where the current animation should be on that clock. It can jump, it can cause jumps, this was really noticeable back when Safari would pause all animations on Chester. So if you'd be scrolling or swiping all the animations would pause.

That problem would happen all the time in that situation because the CSS was trying to jump ahead to where the system clock was, but it wasn't actually bothering to wait and do its animations. This is less of a problem today, but every once in a while you still see some residuals from that.

So we're going to need something a little bit more robust, you also have to consider that animations. Say you have a page with an animation on it that takes ten seconds, right? It's a full ten second long animation, didn't put a play button on it like I told you to but that's all right, I understand, we all go through that phase.

So that site takes a full, I don't know, five seconds to load. It's a slow connection or you're just really, really bad at condensing all your CSS into one file. That's okay, we all go through that phase too. So your browser the page isn't fully rendered until five seconds in.

The animation will actually be running from five seconds in itself half way through its completion. When the page is fully rendered that's why we use things like load events and scope those animations to classes like loaded. Because that way we know they're not starting on the system clock before anything's on the page.

So that's a gotcha to remember about animations. They're always paying attention to the system clock so make sure they're starting when you tell them to.
Rachel Nabors: So there are a couple of ways around this, one is overloading keyframes. We can overload the keyframes block, this is actually a handy technique you can use, check this out.

So there's only one animation dash whatever property that you can use inside a keyframes block, and that is an animation timing function. Believe it or not, you can change the animation timing function halfway through your keyframes block. You could be changing it from linear to ease in, and then make it ease out on the next one down.

This is pretty cool, you can do bounces with this. Here's a demo, I'm going to demo this one for you because I'm not going to make you go through this one on your own. I like it too much for that, so let's change this view and notice he sits down.

My goodness, how does he sit down with only one CSS animation what did I do what black magic and sorcery have I engaged in for this? Well, here it is combined cycle and that looks so simple, how did I do that? Well, combined cycle is a little complex, you'll notice that the background position at 0% is fine but I'm also setting the steps to 12 in here the animation timing function.

Now at exactly 66.6666, not a bad sign, I change that background position. But then at 0.00 something 1% later, so the change is instantaneous It's not animated between these. I transition the background over to the negative 400 pics and scooted over to the other side of it's sprite where there's the sit down cycle and use the steps five function there.

There you go, so if I didn't put steps five in here,
Rachel Nabors: It would use linear, or pardon me, it would use ease instead of using the steps.
Rachel Nabors: So yes and by the way, keep in mind when you're setting animation timing functions inside key frames block. The functions describe the timing function that the next key frame block should, the next part of the key frame block should use.

Like to get from 0% to 66% we going to use steps 12 and then from 66% to 66.67% to 100% we're going to use steps 5. Sometimes I get a little tripped up about where it should be put. Putting my custom animation timing functions in my key frames box but that's how you can keep in mind.

Rachel Nabors: So there are some downsides to this, and they are pretty big downsides. You don't get to loop those animations, I mean what would we be doing? Looping tuna sitting down? Come on seriously this would be so sad, this is the most that we can do. Let's see what it looks like when we try to run it twice, while he walks and he sits down and then he walks and he sits down.

I don't get to loop him. I don't get to loop his walking cycle twice, I don't have any control over that by overloading the the key frames I have, let go of that ability. You only get one timing function at a time for all animation properties, so that means even if I were to change his background color like in between 0% and 100% like let's see.

Let's say I'm going to say background-color red. All right, and you like that looked good, Rachel maybe you could do background color white down here.
Rachel Nabors: But you can't actually, actually that's kind of hard to see maybe I'll slow this down. No, I can't actually but the point is that the colors are tied, so you think, well what if you put that to 30%.

So it's like 30%, background color white. Nope, it's still being sucked in by that one, timing function.
Rachel Nabors: And lastly, it's mathy, you've gotta do a little bit of math to get the timing right. Of course, you could write a Saas mixin that does your math for you, that's what I do.

But not all of us want to do that, so for the rest of us we're going to have to come up with more robust technique. And for that, we have something very special in our friend JavaScript, we have specific for animation event listeners. All right, let me describe each of them before must have JavaScript event listeners for handling CSS animations and transitions are.

Animationstart which fires when an animation begins animation end which fires when the animation has completed or stopped it will never fire if it is running infinitely. Animation iteration which fires every time it has completed its route from 0% to 100% or if you've got it set to reverse from 100% to 0%.

And transitionend which fires only when a transition has completed. I'm surprised that there's no transitionstart event, but okay, whatever, we'll go with it. Thanks W3C, maybe one day. Maybe there will be a need for it, a demonstrable need. We can scope these to some fairly complex chains but you must keep in mind there's one gotcha.

These will fire for every animation or transition on an event. So it makes sense if you're good with your CSS JavaScript foo, do a little bit of detection to make sure that the event firing the transition or animation on end, etc., is the one you're expecting. Maybe it's the correct property.

Maybe it's the correct rule.
Rachel Nabors: So of course, there are browser prefixes to keep in mind. Number one Webkit it's all camel case. WebkitAnimationIteration uses for Webkit based browsers. Microsoft of course starts with capitals MSA. MSAnimationIteration for IE 10 and everybody else uses all lowercase, no camelCase. I kind of wish that the i were capitalized, I would have appreciated that because they all look the same to me.

I don't know why it's like that, I probably it JavaScript function to map them all but that's just me. But anyway

Ready to take your code to the next level?

Intense courses with world-class teachers and unlimited access to our growing library of videos for the great price of $39 per month.

Get Unlimited Access Now