How to time your CSS animations in JavaScript

2 min read


By Einar Afiouni


December 5, 2022

Changing states is probably one of the most common things we do as javascript developers. This could be anything from checking a checkbox to closing a modal. And often we would like to show this transition between states to the end user in the form of animations. For example, you would probably want to fade the modal out before removing it from the DOM. But how does JavaScript know when the animation has ended to remove the component from the DOM?

Let's look at a simple example:

In this very simple example we have three lines of text. When the middle line is clicked, we apply a display: none to the element so that we can remove it from the DOM.

Now if we wanted to slowly fade out the text before we could instead use an animation

But now the element is never truly removed from the DOM, only invisible. So how do we solve this? We could set a timer when the text is clicked and then hide it after the duration of the animation has passed

This works, but is fragile. If we were to change the animation duration to anything else we'd either have to remember to change the timeout, or it would just disappear either too late or too early. So can we do this more robust?

Turns out we can! We can listen to the elements animationend event and hide the element only after the animation has ended.

This way, no matter what the animation duration is set to, the element will only become hidden after the animation has actually ended.

We can also listen to other animation events like animationstart, animationcancel and animationiteration. In React you can add these event-listeners with onAnimationEnd etc directly on the element.

If one element has multiple animations and you want to do different things based on which animation is running, you'd have to check in the animationend listener what state is running now, either through classes or some internal state in your javascript code.

Up next...