CSS animation-fill-mode Property

Beginner
6 min read
Updated: Oct 2026
3 examples
Live preview

Definition and Usage

The animation-fill-mode property sets how an animation applies styles before and after it plays. By default the element snaps back to its normal CSS when the play is not running.

forwards keeps the last keyframe after the play ends. backwards applies the first keyframe during an animation-delay. both does both. It applies to all elements, including ::before and ::after, and it is not inherited. Fill mode does not remove motion for someone who set prefers-reduced-motion.

Standard-track.

Not deprecated and not experimental. none, forwards, backwards, and both have been widely available since 2015.

CSS Syntax

syntax.css
animation-fill-mode: none | forwards | backwards | both | initial | inherit;

The initial value is none. For several animations, separate the keywords with commas, in the same order as the names.

Property Values

ValueDescriptionTry it
noneDefault. No animation styles before or after the playTry it
forwardsKeeps the last keyframe after the play endsTry it
backwardsApplies the first keyframe during the delay, before the play startsTry it
bothUses the rules for forwards and backwards togetherTry it
initialSets this property to its default value, noneTry it
inheritInherits this property from the parent elementTry it

How to Use animation-fill-mode

Play a short fade once, add a delay so backwards can show, then pick the fill.

  1. Write @keyframes fade whose from and to both differ from the resting style.
  2. Set animation-name, animation-duration: 1s, and play it once (the default count).
  3. Add animation-delay: 1s when you want to see backwards or both.
  4. Set animation-fill-mode to forwards, backwards, or both.
PieceRequired?Role
A named animationYesFill mode has no keyframes to keep without @keyframes
A finished playFor forwardsAn infinite loop never reaches an after state
A delayFor backwardsWithout a delay, the first keyframe has no wait to fill

Live Preview

Wait one second, then a one-second fade from opacity 0.25 to 0.5. Only animation-fill-mode changes. Apply again to replay.

none snaps back. forwards keeps the end. backwards fills the delay.

Result

Fade

animation-fill-mode: none. Normal style during the delay. Snaps back after.

CSS Examples

Each snippet uses the same fade and a one-second delay. The only change is animation-fill-mode. Use Try It Yourself for a live editor.

Example 1 — Keep the End

After the fade, the word stays at opacity 0.5 instead of snapping back.

CSS
<style>
  @keyframes fade {
    from {
      opacity: 0.25;
    }

    to {
      opacity: 0.5;
    }
  }

  p {
    animation-name: fade;
    animation-duration: 1s;
    animation-delay: 1s;
    animation-fill-mode: forwards;
  }
</style>

<p>Fade</p>
Try It Yourself

How It Works

  1. Name the steps. fade goes from opacity 0.25 to 0.5.
  2. Play once. Default iteration count is 1, so the animation can finish.
  3. Wait, then fade. animation-delay: 1s holds the normal style first. Then the one-second play runs.
  4. Keep the end. forwards leaves the word at the to keyframe after the play ends.

Example 2 — Fill the Delay

During the wait, the word already looks like the first keyframe.

CSS
<style>
  @keyframes fade {
    from {
      opacity: 0.25;
    }

    to {
      opacity: 0.5;
    }
  }

  p {
    animation-name: fade;
    animation-duration: 1s;
    animation-delay: 1s;
    animation-fill-mode: backwards;
  }
</style>

<p>Fade</p>
Try It Yourself

How It Works

  1. Use the same fade. First keyframe is dim. Last keyframe is half opacity.
  2. Keep the delay. Without a wait, backwards has almost nothing to show.
  3. Fill the wait. backwards applies the from keyframe as soon as the rule is set, so the word starts dim.
  4. Then snap back. After the play ends, fill mode is only backwards, so the word returns to its normal full opacity.

Example 3 — Before and After

Dim during the delay. Stay at half opacity when the play ends.

CSS
<style>
  @keyframes fade {
    from {
      opacity: 0.25;
    }

    to {
      opacity: 0.5;
    }
  }

  p {
    animation-name: fade;
    animation-duration: 1s;
    animation-delay: 1s;
    animation-fill-mode: both;
  }
</style>

<p>Fade</p>
Try It Yourself

How It Works

  1. Same steps and delay. One second wait, then one second of fade.
  2. Fill both ends. both means backwards plus forwards.
  3. During the wait. The first keyframe shows, so the word is dim before motion starts.
  4. After the play. The last keyframe stays, so the word remains at opacity 0.5.

Edge Cases & Pitfalls

If the fill seems missing, check the delay, the count, and whether the keyframes differ from the resting style.

loop

forwards needs a finished play

animation-iteration-count: infinite never ends, so there is no after state for forwards to keep. Play a finite count.

delay

backwards needs a delay

With no delay, the first keyframe has no wait to fill. Also, the first keyframe must differ from the element normal style, or the wait looks unchanged.

end

Which keyframe is last depends on direction

With animation-direction: reverse, the last keyframe for forwards is the from side. Direction and iteration count decide which frame stays.

order

The shorthand can wipe the fill

animation: 1s fade sets this property back to none. Write animation-fill-mode after it, or include forwards in the shorthand.

list

One keyword per animation name

animation-fill-mode: forwards, backwards follows the order of animation-name. Fewer keywords than names, and the list repeats.

Browser Support

animation-fill-mode is a browser style property. Node.js, Deno, and Bun do not play it. The versions below include all four keywords.

✓ Baseline · Widely available since 2015

animation-fill-mode

Chrome 43+, Firefox 16+, Safari 9+, Edge 12+, Internet Explorer 10+. none, forwards, backwards, and both share these versions.

97% all four keywords
Google Chrome 43+
Full support
Mozilla Firefox 16+
Full support
Apple Safari 9+
Full support
Microsoft Edge 12+
Full support
Opera 30+
Full support
Samsung Internet 4+
Full support
Internet Explorer 10+
Full support
animation-fill-mode Widely supported

Bottom line: Older Chrome, Safari, and Firefox also accepted a prefixed property. The four fill-mode keywords shipped together with CSS animations.

Key Takeaways

  • Role: which animation styles stay before and after the play.
  • none: the initial value. Outside the play, normal CSS wins.
  • forwards: keep the last keyframe after the play ends.
  • backwards / both: fill the delay; both also keeps the end.

One line: animation-fill-mode decides whether keyframes stick around outside the active play.

Frequently Asked Questions

It sets which animation styles stay on the element outside the active play. none applies none. forwards keeps the last keyframe after the play ends. backwards applies the first keyframe during a delay. both does both.
The initial value is none. Outside the play, the element uses its normal CSS. After the animation ends, it snaps back unless you set forwards or both.
forwards keeps the last keyframe after the animation finishes. backwards applies the first keyframe as soon as the animation is applied, and keeps it during animation-delay. They cover different times.
Use both when you want the first keyframe during the delay and the last keyframe to remain after the play ends. It is forwards and backwards together.
backwards only changes the look during a delay, and only if the first keyframe differs from the element normal style. With no delay, or with a from that matches the resting style, you will not see it.
Chrome 43+, Firefox 16+, Safari 9+, Edge 12+, and Internet Explorer 10 support all four keywords. It is a browser style property, not a Node.js feature.

Next: animation-iteration-count

Set how many times the play runs before forwards can keep the end.

animation-iteration-count tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful