How to Capture CSS3 Animation Events in JavaScript

Share this article

CSS3 animations are smooth and quick to implement but, unlike JavaScript, you don’t have frame-by-frame control. Fortunately, you can apply event handlers to any element to determine the animation state. This permits fine-grained control such as playing different animations in sequence.

Consider this simple CSS3 animation:

#anim.enable
{
  -webkit-animation: flash 1s ease 3;
  -moz-animation: flash 1s ease 3;
  -ms-animation: flash 1s ease 3;
  -o-animation: flash 1s ease 3;
  animation: flash 1s ease 3;
}

/* animation */
@-webkit-keyframes flash {
  50% { opacity: 0; }
}

@-moz-keyframes flash {
  50% { opacity: 0; }
}

@-ms-keyframes flash {
  50% { opacity: 0; }
}

@-o-keyframes flash {
  50% { opacity: 0; }
}

@keyframes flash {
  50% { opacity: 0; }
}

When the enable class is applied to the element with ID anim, the animation named flash is run three times. Each iteration lasts one second during which the element fades out then in.

Three types of event are fired when the animation occurs:

animationstart

var anim = document.getElementById("anim");
anim.addEventListener("animationstart", AnimationListener, false);

The animationstart event is fired when the animation starts for the first time.

animationiteration

anim.addEventListener("animationiteration", AnimationListener, false);

The animationiteration event is fired at the start of every new animation iteration, i.e. every iteration except the first.

animationend

anim.addEventListener("animationend", AnimationListener, false);

The animationend event is fired when the animation ends.

Browser Compatibility

At the time of writing, Firefox, Chrome, Safari, Opera and IE10 support CSS3 animation and the associated event handlers. In addition, Opera, IE10 and the webkit browsers use prefixes and throw in a few case changes for good measure…

W3C standard Firefox webkit Opera IE10
animationstart animationstart webkitAnimationStart oanimationstart MSAnimationStart
animationiteration animationiteration webkitAnimationIteration oanimationiteration MSAnimationIteration
animationend animationend webkitAnimationEnd oanimationend MSAnimationEnd

The easiest way around the prefix shenanigans is to call addEventListener for all prefixed and non-prefixed names using a custom function:

var pfx = ["webkit", "moz", "MS", "o", ""];
function PrefixedEvent(element, type, callback) {
	for (var p = 0; p < pfx.length; p++) {
		if (!pfx[p]) type = type.toLowerCase();
		element.addEventListener(pfx[p]+type, callback, false);
	}
}>code>

Cross-browser event handlers can now be assigned using a single line of code:

// animation listener events
PrefixedEvent(anim, "AnimationStart", AnimationListener);
PrefixedEvent(anim, "AnimationIteration", AnimationListener);
PrefixedEvent(anim, "AnimationEnd", AnimationListener);

The Event Object

In the code above, the AnimationListener function is called whenever an animation event occurs. An event object is passed as a single argument. As well as the standard properties and methods, it also provides:

  • animationName: the CSS3 animation name (i.e. flash)
  • elapsedTime: the time in seconds since the animation started.

We could therefore detect when the flash animation ends, e.g.

if (e.animationName == "flash" && 
    e.type.toLowerCase().indexOf("animationend") >= 0) {
    ...
}

The code could, for example, remove the existing class or apply another CSS3 animation in a specific sequence.

View the CSS3 Animation Events in JavaScript demonstration

The demonstration page displays a button. When it’s clicked, an “enable” class is toggled which starts the flash animation. The state is displayed in a console when an animation event fires. When the animation ends, the “enable” class is removed so the button can be clicked again.

Let me know if you use animation event capturing in any interesting projects.

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like HTML5 & CSS3 For the Real World.

Comments on this article are closed. Have a question about CSS? Why not ask it on our forums?

Frequently Asked Questions (FAQs) on CSS3 Animation and JavaScript Event Handlers

What are CSS3 Animation and JavaScript Event Handlers?

CSS3 Animation is a feature of CSS3 (Cascading Style Sheets) that allows you to animate HTML elements without using JavaScript or Flash. It provides a way to create simple animations directly in CSS code, without any additional resources. On the other hand, JavaScript Event Handlers are functions in JavaScript that are triggered when a specific event occurs. These events can be anything from a user clicking a button, to a page loading, to an animation ending. When combined, CSS3 Animation and JavaScript Event Handlers can create dynamic, interactive web content.

How do I use JavaScript Event Handlers with CSS3 Animations?

To use JavaScript Event Handlers with CSS3 Animations, you need to add an event listener to the HTML element you want to animate. This event listener will trigger a JavaScript function when the animation ends. Here’s a basic example:

element.addEventListener('animationend', function() {
// Code to execute when the animation ends
});

In this code, ‘animationend’ is the event we’re listening for, which is triggered when a CSS3 Animation finishes.

Can I use JavaScript Event Handlers with CSS3 Transitions?

Yes, you can use JavaScript Event Handlers with CSS3 Transitions in a similar way to CSS3 Animations. The event you need to listen for is ‘transitionend’. This event is fired when a CSS Transition has completed.

How can I control the timing of CSS3 Animations with JavaScript?

You can control the timing of CSS3 Animations with JavaScript by using the ‘animation-delay’ property. This property sets a delay for the start of an animation. You can set this property in JavaScript like this:

element.style.animationDelay = '2s';

In this code, the animation will start 2 seconds after the page loads.

How can I repeat a CSS3 Animation with JavaScript?

You can repeat a CSS3 Animation with JavaScript by using the ‘animation-iteration-count’ property. This property specifies the number of times an animation should be played. You can set this property in JavaScript like this:

element.style.animationIterationCount = 'infinite';

In this code, the animation will repeat indefinitely.

Can I use JavaScript to change the speed of a CSS3 Animation?

Yes, you can use JavaScript to change the speed of a CSS3 Animation. The ‘animation-duration’ property controls the length of time that an animation takes to complete one cycle. You can set this property in JavaScript like this:

element.style.animationDuration = '2s';

In this code, the animation will last 2 seconds.

How can I pause and resume a CSS3 Animation with JavaScript?

You can pause and resume a CSS3 Animation with JavaScript by using the ‘animation-play-state’ property. This property sets whether the animation is running or paused. You can set this property in JavaScript like this:

element.style.animationPlayState = 'paused';

In this code, the animation will be paused.

Can I use JavaScript to change the direction of a CSS3 Animation?

Yes, you can use JavaScript to change the direction of a CSS3 Animation. The ‘animation-direction’ property defines whether an animation should play in reverse on alternate cycles. You can set this property in JavaScript like this:

element.style.animationDirection = 'reverse';

In this code, the animation will play in reverse.

How can I use JavaScript to detect the end of a CSS3 Animation?

You can use JavaScript to detect the end of a CSS3 Animation by adding an event listener for the ‘animationend’ event. This event is fired when a CSS3 Animation has completed. Here’s how you can do it:

element.addEventListener('animationend', function() {
// Code to execute when the animation ends
});

Can I use JavaScript to change the animation-timing-function of a CSS3 Animation?

Yes, you can use JavaScript to change the ‘animation-timing-function’ of a CSS3 Animation. This property specifies the speed curve of an animation. You can set this property in JavaScript like this:

element.style.animationTimingFunction = 'ease-in';

In this code, the animation will start slowly, and then accelerate.

Craig BucklerCraig Buckler
View Author

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.

animationCSS3effectseventsHTML5 Dev CenterHTML5 Tutorials & Articlesjavascript
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week