The CSS Animation Events

by kirupa   |   14 April 2013

When your CSS animations are playing, what they do isn't just purely visual. Behind the scenes, they fire events at key points in their life. In this short tutorial, you will learn all about these events and how to listen to them in JavaScript.

Let's get started.

Meet the Animation Events

When an animation plays, the three animation-related events that get fired are:

The names of these events should give you a big clue on when they make an appearance! The animationstart event shows up at the start of an animation, the animationend event shows up in the end when an animation has finished, and the animationiteration event makes an appearance at the beginning of each animation iteration with the exception of the first one.

To look at this visually, the following diagram of a simple animation that runs for three iterations may help:

the animation events diagram

One thing you need to be aware of is that not all of these events will fire. The only event you can always rely on is the animationstart event. Your animationteration event will start firing at the beginning of your animation's second iteration - provided your animation is set to run more than once. If your animation runs only once, the animationiteration event never gets a change to be heard. Your animationend event will only fire if your animation does in fact end at some point. If your animation runs forever, there is no end to it and...if there is no end, there is no animationend event to listen to!

What the Code Looks Like

Now that you've learned a little more about these events, let's take a look at them in JavaScript.

Below is the code:

var element = document.querySelector("#blah");

element.addEventListener("animationstart", start, false);
element.addEventListener("animationiteration", update, false);
element.addEventListener("animationend", end, false);

function start(e) {
	// react to the animationstart event
}

function update(e) {
	// react to the animationiterationevent
}

function end(e) {
	// react to the animationend event
}

As with all event handling, there are two parts to the code you see. The first part is setting up the event listeners to listen to the events:

var element = document.querySelector("#blah");

element.addEventListener("animationstart", start, false);
element.addEventListener("animationiteration", update, false);
element.addEventListener("animationend", end, false);

The second part is defining the event handler that does something when the event is over heard:

function start(e) {
	// react to the animationstart event
}

function update(e) {
	// react to the animationiteration event
}

function end(e) {
	// react to the animationend event
}

See, pretty simple! There is one major thing missing in the code I've shown so far, and that is the vendor prefixes needed to ensure you can listen to these events on all the major browsers. With the vendor prefixes added in, your above code would actually look as follows:

var element = document.querySelector("#blah");

element.addEventListener("animationstart", start, false);
element.addEventListener("mozAnimationIteration", start, false);
element.addEventListener("webkitAnimationIteration", start, false);
element.addEventListener("msAnimationIteration", start, false);

element.addEventListener("animationiteration", update, false);
element.addEventListener("mozAnimationIteration", update, false);
element.addEventListener("webkitAnimationIteration", update, false);
element.addEventListener("msAnimationIteration", update, false);

element.addEventListener("animationend", end, false);
element.addEventListener("mozAnimationEnd", end, false);
element.addEventListener("webkitAnimationEnd", end, false);
element.addEventListener("msAnimationEnd", end, false);

function start(e) {
	// react to the animationstart event
}

function update(e) {
	// react to the animationiteration event
}

function end(e) {
	// react to the animationend event
}

To say the vendor prefixes make our code verbose is an understatement. Fortunately, all of the latest versions of the popular browsers support animations without requiring vendor prefixes, so this is just for the older versions. Hopefully this vendor prefixing is something you can ignore in the near future altogether.

The Event Object

Your animation events carry with them some additional data as part of their event arguments. These event arguments are captured in our event handlers via the cleverly named e variable as seen in, for example, on start:

function start(e) {
	// react to the animationstart event
}

The two interesting properties you can find as part of the animation event arguments are:

  1. animationName
  2. elapsedTime

The animationName property, as you can guess, returns the name of the animation that this particular event was fired from. The elapsedTime property displays the total time in seconds that has elapsed between this function getting called and when the animation actually started. Of course, for the animationstart event, the elapsed time will be 0 seconds because, well, the animation just started.

The Usefulness of These Events

At this point, now that you know all about the animation events and how to use them, is to...figure out a reason to actually use them in the real world! This is much harder than it sounds. When would you ever want to react to the start, iteration, and end states of an animation? Outside of demos explaining how these events work or some contrived examples for controlling your animation, I can't think of any good reasons when I would want to use them in real life. If you have some good scenarios, feel free to post on the forums and let me know.

The only animation event I can see myself using would be one that gets fired when an animation keyframe is reached. With such an event, you can synchronize various parts of your page as different keyframes in your animation get hit. You can display your animation progress. You can pause at an interesting keyframe. There are a lot of cool and practical things you can do. Alas, such an event does not exist. You can find some 3rd party implementations that try to fill this gap, but they were too complicated and had some unwanted quirks when I tried a handful of them.

In a nutshell, the three events you have aren't very useful. The one event that would be useful you don't have. As the characters in the Sopranos despondently say when faced with something they can't do anything about, "Whaddya gonna do?"

Getting Help

If you have questions, need some assistance on this topic, or just want to chat - post in the comments below or drop by our friendly forums (where you have a lot more formatting options) and post your question. There are a lot of knowledgeable and witty people who would be happy to help you out

Share

Did you enjoy reading this and found it useful? If so, please share it with your friends:

If you didn't like it, I always like to hear how I can do better next time. Please feel free to contact me directly via e-mail, facebook, or twitter.

Brought to you by...

Kirupa Chinnathambi
I like to talk a lot - A WHOLE LOT. When I'm not talking, I've been known to write the occasional English word. You can learn more about me by going here.

Add Your Comment (or post on the Forums)

blog comments powered by Disqus

Awesome and high-performance web hosting!
BACK TO TOP
new books - yay!!!