I was recently working on some code that would handle a toggling menu’s open-close state after the animation had finished. In order to do this, we used the transitionend
event to determine when we should modify the state of the DOM nodes to show the new state correctly. However, when the animation was ending it appeared that nothing was happening. After dropping in a debugger
statement, it became clear that what was really happening was that it was firing twice—in quick succession—toggling the element open and closed so quickly that there was no visual effect at all.
Here’s a similar example. Clicking on Hello
should show Bye
once the animation is complete, but it doesn’t because of behavior of multiple transitions.
TL;DR;
The transitionend
event is firing once for each property that is being animated, causing our toggle to fire multiple times. This results in an open-and-close action instead of just the open.
Specifying the propertyName
in your transitionend
event handler can prevent those handlers from doing more than they should. If you want to get right to the solution, jump down to Which Event do I Use? If you want to see some examples and get a feel for why this is happening, read on.
How to Solve This
Let’s look at a simple example to start.
This will fire one event with a property-name
of background-color
.
If we change the transition
to include a transform, we still have one transition property, but it has multiple values.
You’ll also probably notice that each event fires at the end of its specified time, which is most likely what you would expect and want.
If we change the property we’re animating to, for example, border-color
, we get an interesting result.
This will give us 4 events, one for each side of the box:
border-right-color
border-bottom-color
border-left-color
border-top-color
Other shorthand CSS properties (such as padding, border-width, etc.) will also respond with multiple events.
Which Event Do I Use?
Now that you understand how each of these events is firing and when, you need to be able to know which propertyName
you want to trigger your code. You can do this by using the propertyName
key on the event object (it’s what I logged to the console in the samples). It will contain the name of the property that just finished, so you can isolate your JavaScript to execute based on specific transitions.
So, looking back at the original example, we can fix the problem by making sure that we only fire the toggle
code based on one specific transition ending:
Go Forth And Animate
The transitionend
event is a great tool to use when you need to sync up some JavaScript actions with your CSS animations. Just remember that if you’re animating more than one property, you’re going to get more than one event fired.
Sparkbox’s Development Capabilities Assessment
Struggle to deliver quality software sustainably for the business? Give your development organization research-backed direction on improving practices. Simply answer a few questions to generate a customized, confidential report addressing your challenges.