CSS animations are an easy, lightweight method to add flair to a web page. They’re not too difficult to implement, and they won’t slow down your pages like videos, gifs, or Flash animations are notorious for.
However, sometimes these animations might not behave exactly how you expect or want them to, simply because of how CSS animations work by default
For example, say I want to animate a car driving across the screen for my taxi/ridesharing/delivery website. Watch what happens when the animation ends:
Did you see that? (If not, click Rerun in the bottom right.) After the car stops moving, it jumps back to its pre-animation position. It would look much better if the car stayed on the other side of the screen when finished, right? How can we make that happen?
The answer is with the CSS property animation-fill-mode. In this guide, we’ll explain what this property does and why it might be the hidden CSS property your animations need to work.
The animation-fill-mode CSS property controls the styles of an animated element outside of its execution. In other words, it controls what the element looks like before the animation starts and/or after the animation ends.
By default, a CSS animation will only apply its styles while the animation is in progress. This is why we saw the car reset in the example above — once the animation ended, the image element reverted to its initial style (i.e. its initial position). With animation-fill-mode, we can change this.
CSS animation-fill-mode Syntax
The animation-fill-mode property is written as follows:
As with other animation-* properties, animation-fill-mode is placed in the declaration block for the element you want to animate.
CSS animation-fill-mode Values
animation-fill-mode takes four main values: forwards, backwards, both, and none. Let’s unpack each one of these.
When assigned animation-fill-mode: forwards, the target element will retain the style values that are set in the final keyframe of the animation. After the animation ends, the element will not reset its styles.
Wait, this sounds like exactly what we need for our car animation! Let’s try the example again, this time with animation-fill-mode: forwards applied.
As we’d hoped, the car stays on the right side of the screen when the animation terminates.
Note that the direction of the animation, set by the animation-direction property, determines what the final frame of the animation looks like. For example, if the animation-direction is normal (the default), the final keyframe will be at 100% (or to). If the direction is reverse, however, the final keyframe (and thus the styles that are retained) is at 0% (or from).
The forwards value is probably the most common and useful value for this property. Use it to prevent an animated element from resetting visually after the animation finishes.
When assigned animation-fill-mode: backwards, the target element will take the style values set by the first keyframe of the animation during the animation-delay period. animation-delay sets a time delay until an animation begins, and animation-fill-mode applies during this delay.
To demonstrate, I’ve added a couple more rules to our car example. There’s an animation-delay of 3s (three seconds) and an extra style to the @keyframes declaration that rotates the car (to make it look like it’s going fast, as cars do).
With animation-fill-mode: backwards applied, the image adopts the styles from the first keyframe during that three-second delay period. At the end, the car returns to its pre-animation style. (If you didn’t catch it the first time, click Reload in the bottom right.)
The backwards value isn’t as widely applicable as forwards, but it may be useful with more complex animation sequences.
Also, note that setting animation-direction: reverse will make the element take on the styles of the final keyframe of the animation instead of the first keyframe.
animation-fill-mode: both applies the rules of both backwards and forwards: The element will adopt the styles of the first keyframe before the animation begins, and the styles of the last keyframe after the animation ends.
This example looks like the previous, except the car doesn’t reset at the end. Bravo!
none is the default value for animation-fill-mode. With it, the animation stylings will not apply to the element before or after the animation sequence. You could use this value to override a parent value — otherwise, it’s not necessary.
initial and inherit
animation-fill-mode also takes the global values initial and inherit. Initial sets the value to its default (none). inherit sets the value the same as its parent element.
Control your animations with animation-fill-mode.
The animation-fill-mode property may not be the most glamorous CSS property, but it can prove necessary for many types of animations. Including it can help your animations look cleaner and prevent them from resetting at the end of a sequence. For that reason alone, it’s worth knowing.
Originally published Sep 2, 2021 7:00:00 AM, updated April 20 2022