Restarting a CSS animation with the use of the
reflow) browser process.
Restarting an animation, unfortunately, is not as easy as I thought by adding and removing classes.
Yes, that frustrating place where no developer wants to go. To have absolutely no idea how to fix it after trying everything with long hours of researching and debugging.
If you are reading this, you are a web developer and you know what I mean. But worry no more my friend! In this article, I will show you a simple fix to use and properly restart a CSS animation, so your cool animations stay cool.
But first, let me ask you a couple of questions to make sure you are reading the right article and not wasting your time.
- Trying to synchronise CSS animations on various elements?
- Restarting an animation on a user event? (Restarting a button animation on mouse-hover.)
If you answered “yes” to at least one of them, this article is for you and, hopefully, you will find it useful.
So, after having been in that horrible situation a number of times, my drive for curiosity and determination to end those never-ending times of staring at a screen, I have gathered a few possible fixes for properly restarting an animation.
However, I will present you with the simplest and easiest one to add to your code. Without further ado, let’s get right into it.
Removing and Adding the Class Won’t Do the Trick#
Removing and adding the class won’t do the trick. Sorry.
But you were close! So close indeed, that you are missing only a single magic line of code.
However, to understand why this line will fix the issue, we will first have to make sure we know what a DOM reflow or layout is.
Simply put, the DOM reflow is a user-blocking operation that computes the layout of the document. A reflow on an element is the calculation of its dimensions and position in the document.
There are many ways in which you can trigger a DOM reflow operation in the browser. For an exhaustive list, check out this gist.
For the sake of simplicity, I will show you only one way but feel free to choose anything that is most suitable for your needs.
Performance Danger ahead#
And here comes great responsibility! Bear in mind that the DOM reflow can be an expensive operation, requiring a lot of CPU power and, because it is a blocking operation, it can cause unwanted, bad user experience.
Make sure that you minimise reflow/layout events throughout your website. Knowing more about it and knowing how to control it will make you a true dev ninja.
Now, back to my point. What makes reflow useful for restarting CSS animations is the process during this calculation, which updates the properties of the elements in the DOM and they are then reinitialised.
Meaning, the animation will run again like it’s the first time the animated element has been rendered.
Triggering a DOM Reflow#
We can simply trigger a DOM reflow by requesting the element’s
void element.offsetWidth; // or similarly void element.offsetHeight;
$("#element").width(); // or similarly $("#element").height();
void? Because we don’t care about the returned value, we just want to request the element’s dimensions which will trigger a reflow event.
Restarting a CSS Animation#
For properly restarting your CSS animation, you would ideally like to trigger a reflow event between removing and adding your CSS classes triggering the animation, as shown below:
var element = document.getElementById("element"); element.classList.remove("animate"); // trigger a DOM reflow void element.offsetWidth; element.classList.add("animate");
$("#element").removeClass("animate"); // trigger a DOM reflow $("#element").width(); $("#element").addClass("animate");
This instructs the browser to recalculate an element’s
width, thus causing a reflow in the DOM. The reflow event triggers the animation to run from the start.
Best practise: I would recommend triggering the reflow as higher up the tree as possible to minimise subsequent reflows that might be triggered on children elements.
I hope you had a great read and found the fix you were looking for. Let me know if this was useful to you and any other cool ways you are using to fix this issue.
I barely touched the DOM reflow/layout thing, so if you are interested in learning more about how to minimise it check out my other article, Web Performance: Minimising DOM Reflow/Layout Thrashing.
Have a good day!