I’m sure just about all of us working in front-end development have fiddled with CSS keyframe-based animations at some point. Some of us may have even created some pretty complex demos and experiments with this feature.
If you want a comprehensive introduction to the topic, my 2011 article on Smashing Magazine is still a good option. In this article, however, I wanted to focus on a single part of the CSS Animations spec: the animation-fill-mode
property.
This is the one animation-based property that isn’t very self-explanatory. For example, nobody really gets confused by animation-name
, animation-duration
, and so forth… But what on earth does “fill mode” mean? Let’s briefly consider this, with some examples.
The Syntax for Defining a fill-mode
As you might already know, a basic keyframe animation is defined using the @keyframes
at-rule. But the keyframes won’t do anything unless you associate them with an animation name. Here’s a shorthand animation
property declaration, so you can see what I mean:
.example {
animation: myAnim 2s 500ms 2 normal ease-in forwards;
}
And of course, this same shorthand line can be expanded to:
.example {
animation-name: myAnim;
animation-duration: 2s;
animation-delay: 500ms;
animation-iteration-count: 2;
animation-direction: normal;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
}
The animation-fill-mode
property is defined last in both examples, and in both cases the value is set to “forwards”. We don’t have to define it last, but that might be a good practice to get into.
Again, even if you’ve never used CSS animations, you can probably figure out what everything in that declaration above is doing – except animation-fill-mode
.
The Spec Definition of fill-mode
So what does the spec say about this property?
The
animation-fill-mode
property defines what values are applied by the animation outside the time it is executing.
As it goes on to explain, the time “outside” of execution, specifically, is referring to the time between when the animation is applied to the element, and the time that the element actually starts animating. Basically, with a fill-mode value, you define the appearance of your animated element outside of the time the animation is taking place, but after the animation has been applied. Might sound confusing, but you’ll see what I mean in a moment.
Let’s build on that basic definition (which might still be a bit confusing) by looking at each of the possible values.
Breaking Down the Values
The animation-fill-mode
property can accept one of four values: none
, forwards
, backwards
, or both
. Here’s a breakdown of each.
Value: none
This is the initial, or default value for animation-fill-mode
. The only time you would define a value of none
without being superfluous would be if you are setting it via JavaScript to change it from one of the other values, or if you’re overriding something in the cascade.
To understand what a value of none
does, here’s a CodePen demo showing an animation with no animation-fill-mode
defined (thus, it has a value of none
):
See the Pen Example with animation-fill-mode: none by SitePoint (@SitePoint) on CodePen.
You can see that in most cases, a fill-mode of “none” is not what you’ll want. Remember that fill-mode defines how the element will look, outside the time that the animation is executing.
In this example, the ball starts out red, then fades to pink while at the same time moving to the right and changing size. It would be preferable if, when the animation finished, the ball stayed small, pink, and off to the right. This will avoid the ugly jump back to the start when the animation finishes.
Value: forwards
Let’s change our ball animation to have a fill-mode value of “forwards”:
See the Pen Example with animation-fill-mode: forwards by SitePoint (@SitePoint) on CodePen.
Now you can see the benefit of using animation-fill-mode
and why a value of forwards
is used more than any other. When we define it with this value, we are telling the browser that we want our animated element to hold on to its final set of styles, as defined in the last keyframe. This way, we don’t get that final jump back to the initial state of the element before it started animating (the “reset” button that I’ve added to the demo does this for us).
Value: backwards
Let’s change the value to backwards
— what happens now?
See the Pen Example with animation-fill-mode: backwards by SitePoint (@SitePoint) on CodePen.
Notice that the behavior in this demo is exactly the same as the first demo that has an animation-fill-mode
value of “none”. Why is that?
In contrast to forwards
, a value of backwards
, upon finishing the animation, gives the element the styles that it had before the animation began. This makes more sense when we see what the spec says for the value backwards
:
During the period defined by
animation-delay
, the animation will apply the property values defined in the keyframe that will start the first iteration of the animation. These are either the values of thefrom
keyframe […] or those of theto
keyframe.
To demonstrate this, I’ve made two modifications to the demo:
- Added a “from” keyframe with a different color for the ball.
- Added a delay using the
animation-delay
property.
Here it is:
See the Pen Example with animation-fill-mode: backwards (2) by SitePoint (@SitePoint) on CodePen.
Now you can see that as soon as you push the “Start The Animation” button, the ball turns blue. This is because there is a noticeable delay. Technically, every animation has a default delay, but the delay is 0s
, so you don’t really see the value of backwards
in such a case, and you certainly don’t see it if the styles in the initial keyframe are the same as those prior to when the animation begins. With the same styles and the same delay in place, removing the value backwards
would cause the ball to stay red until the animation begins.
To be honest, I don’t really see a lot of practical use for the value backwards
. It’s hard to imagine too many scenarios where the animation has different styles in the first keyframe than it does in the static pre-animation state of the element. But I’m willing to hear some use cases if you have any ideas.
Value: both
The final value we’ll look at is a value of both
. This value tells the browser to apply the effects of both forwards
and backwards
.
Let’s keep the same styles in our demo and see what happens when we give it a value of both
:
See the Pen Example with animation-fill-mode: both by SitePoint (@SitePoint) on CodePen.
Not rocket science. As you can see, during the initial delay period, the initial keyframe styles are applied, and then the animation finishes and freezes with the styles from the final keyframe (which is, as mentioned, often what you will want). And again, this value would not be very different from just using forwards
if it were not for the delay and the alternate color defined in the first keyframe.
Some Notes and Tips
Based on the above, along with some details in the spec, here are some things to take note of:
- Although I’ve somewhat minimized the importance of the values
backwards
andboth
, these could come in handy in complex animations that are controlled by scripting or user input. Use cases will abound (think: games), but only with experimenting and innovation. - The effect of the
forwards
andbackwards
values are reversed in cases where theanimation-direction
property is set toreverse
. If you fiddle with the demo, you’ll see how this works. - Although I said that
animation-fill-mode
accepts only four values, remember that there are CSS-wide property values that can also be used. - In earlier versions of the spec,
animation-fill-mode
was not part of the shorthandanimation
property but it seems like all browsers that support keyframes are fine with it in shorthand. - When using animation shorthand and choosing a custom name for your animation, don’t use a name that matches valid fill-mode values (like “reverse” or “forwards”), otherwise the browser will parse the shorthand declaration assuming the name is actually a fill-mode value.
Conclusion
I hope this summary has helped you understand this property a little better. Some of this research certainly helped me understand it a little better. If you’ve done some unique things with animation-fill-mode
or have any unique use cases for the different values, or corrections to this article, let us know in the discussion.
Frequently Asked Questions about CSS Animation Fill-Mode Property
What is the significance of the CSS animation-fill-mode property?
The CSS animation-fill-mode property is a crucial aspect of CSS animations. It defines how an animation should apply styles to its target before and after its execution. This property helps in controlling the intermediate state of an element during the animation process. It can take four values: none, forwards, backwards, and both. Each value determines how the animation affects the element at different stages, providing developers with greater control over their animations.
How does the ‘forwards’ value in animation-fill-mode work?
The ‘forwards’ value in the CSS animation-fill-mode property ensures that the element retains the computed values set by the last keyframe encountered during the animation. This means that after the animation ends, the styles defined in the last keyframe will persist on the element, instead of reverting back to the original styles.
Can you explain the ‘backwards’ value in animation-fill-mode?
The ‘backwards’ value in the CSS animation-fill-mode property applies the styles from the first keyframe to the element during the period before the animation starts. This means that if there is a delay before the animation begins, the element will take on the styles defined in the first keyframe during that delay period.
What does the ‘both’ value mean in animation-fill-mode?
The ‘both’ value in the CSS animation-fill-mode property combines the effects of ‘forwards’ and ‘backwards’. This means that the styles from the first keyframe are applied before the animation starts, and the styles from the last keyframe are retained after the animation ends.
What happens when the animation-fill-mode property is set to ‘none’?
When the CSS animation-fill-mode property is set to ‘none’, the animation will not apply any styles to the element before it starts or after it ends. The element will only be affected by the animation during the period when the animation is actively running.
Can I use multiple values for the animation-fill-mode property?
No, the CSS animation-fill-mode property can only take one value at a time. You can choose from ‘none’, ‘forwards’, ‘backwards’, or ‘both’ based on your specific requirements for the animation.
Is the animation-fill-mode property supported in all browsers?
The CSS animation-fill-mode property is widely supported in all modern browsers, including Chrome, Firefox, Safari, and Edge. However, it is not supported in Internet Explorer.
How does the animation-fill-mode property interact with the animation-delay property?
The CSS animation-fill-mode property works in conjunction with the animation-delay property. If the animation-fill-mode is set to ‘backwards’ or ‘both’, and there is an animation-delay, the styles from the first keyframe will be applied during the delay period.
Can the animation-fill-mode property be used with keyframes that have percentage values?
Yes, the CSS animation-fill-mode property can be used with keyframes that have percentage values. The ‘forwards’ and ‘backwards’ values will apply the styles from the keyframe closest to 0% and 100% respectively.
What is the default value of the animation-fill-mode property?
The default value of the CSS animation-fill-mode property is ‘none’. This means that by default, the animation will not apply any styles to the element before it starts or after it ends.
Louis is a front-end developer, writer, and author who has been involved in the web dev industry since 2000. He blogs at Impressive Webs and curates Web Tools Weekly, a newsletter for front-end developers with a focus on tools.