animation-fill-mode in CSS: keeping an animation's last frame instead of snapping back

animation-fill-mode decides whether an element keeps an animation's final state or receives its first state before it even starts.
4 min read
Believemy logo

A notification that slides in from the top of the screen, then vanishes instantly once the animation ends, snapping back to its invisible starting position: this surprising behavior, very common among beginners, almost always comes from forgetting the animation-fill-mode property.

By default, a CSS animation has no memory of what happens before it starts or after it ends: it plays its sequence, then the element goes right back to looking exactly as it would have without it. animation-fill-mode changes that by extending the effect of the animation's first or last frame beyond its actual duration.


Definition

animation-fill-mode decides which CSS values an element keeps before an animation starts and after it finishes. It accepts four main values: none, which changes nothing (the default behavior), forwards, backwards, and both, which combines the two.

ValueEffect
noneNo effect kept, the default behavior
forwardsKeeps the last frame's state after it ends
backwardsApplies the first frame's state before it starts
bothCombines forwards and backwards


forwards: keeping the last state

forwards is the value used most in practice: it makes the element keep the styles defined in the last step of the CSS animation once it finishes, instead of instantly reverting to whatever it looked like before the animation.

CSS
@keyframes slide-in {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.notification {
  animation: slide-in 0.4s ease-out forwards;
}


backwards: applying the first state before the start

backwards is mostly used together with animation-delay: it applies the first step's styles right from page load, even before the delay has run out and the animation actually begins. Without it, the element briefly shows its natural final state before suddenly switching to the animation's starting state the moment it kicks off.


The first-frame jump pitfall

The most common issue shows up exactly with delayed animations using animation-delay. Without backwards, the element stays visible in its normal state throughout the delay, then jumps abruptly to the animation's starting state the instant it begins, an unpleasant and entirely avoidable visual glitch.

Good to knowWhenever an animation uses animation-delay, set animation-fill-mode to both instead of forwards alone. both applies the starting state during the delay and keeps the final state after it ends, avoiding a visual jump at both the beginning and the end of the animation.


A practical shorthand inside the animation property

animation-fill-mode rarely gets written on its own: it usually gets folded directly into the animation shorthand, after the duration, the Easing and timing function and any delay, as in animation: slide-in 0.4s ease-out 0.2s both.

This setting is especially useful for a stack of notifications staggered with different delays, where each one needs to stay invisible before its turn instead of flashing on page load.


Frequently asked questions

QuestionWhat is the difference between animation-fill-mode: forwards and just setting the final styles directly in CSS?

The final visual result is identical, but forwards avoids duplicating values in two different places: without it, the last frame's styles would need to be manually repeated outside @keyframes, risking the two versions drifting apart after a future change.

QuestionDoes animation-fill-mode work with a transition instead of an animation?

No, this property only exists for the animation and @keyframes family. A transition does not have this first-frame jump problem since it always starts from the CSS state actually applied to the element at the moment of the change, never recreating an artificial state.

QuestionIs both always the safest default value?

In the vast majority of cases, yes, unless the element is deliberately meant to show its natural state during the delay before the animation, which remains a legitimate design choice but a rarer need than hiding that delay with backwards.

Related terms

Discover our hTML and CSS glossary

Browse the terms and definitions most commonly used in HTML and CSS development.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.