Command Palette

Search for a command to run...

Hectal
Shots in this scene
SHOT 4.3Beginner ~19 min · shot 3 of 6

Fill Mode, Direction and Iterations

In one line

Fill mode decides what an element looks like before an animation starts and after it ends. Direction, iteration count and a negative delay decide where and how it runs.

0/6 · 0%

Think of it like this

A stage actor. Before the scene starts, they wait in the wings (their own place). During the scene they are on stage. When the scene ends, they either stay on stage or walk back off. Fill mode is that choice: before the start and after the end, does the animation's first or last frame still apply?

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

fill mode
Whether an animation's first frame applies during the delay and its last frame after the end.
iteration
One run of the animation from start to end.
delay
Time to wait before the animation starts. Negative means start part-way in.
alternate
A direction that runs forwards on odd iterations and backwards on even ones.
active duration
Duration × iterations: how long the animation really runs.

Step by step

01Before the start

Replay, pause and step to 500 ms (inside the one-second delay). none and forwards lanes are at their own place (0). backwards and both already sit at the first keyframe, 40 px. They never flash at the wrong place.

02After the end

At 2.3 s: none and backwards are back at 0, because nothing holds the last frame. forwards and both stay at 160 px.

03Where it starts and where it ends

The second example prints each lane's timing: with delay -500 the animation ends at 500 ms (it starts half way through its 1000 ms). It also shows that 1.5 iterations ends half way, and 0s with a fill ends at once at its last frame.

04A held end still wins

forwards keeps the last frame over later style changes (first break-it).

Try it yourself

  1. 1

    Read the end positions

    In the last example Replay and step to the end. The 1.5 iterations box rests half way (70 px), the alternate box is back at 10 px (its last iteration ran backwards), the 0s box is already at 130 px, and the -500ms box started at 70 px.

  2. 2

    Take away the fill

    In the second example remove the word both. Each box jumps back to its own place (0) the moment its animation ends.

Code & diagrams

Try it: interactive

Place the box on the timeline

Set delay 500, iterations 2 and direction alternate. Drag the time slider to before, during and after, and switch the fill mode.

The four fill modes

Replay and step. The dashed lines mark the first (40 px) and last (160 px) keyframes. Look at 500 ms and at 2.3 s.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.
Negative delay, fractions, alternate and zero

All four have fill `both`. Compare where each box finishes.

Press Run to see the page.
00:00.000
animations
0.00s0.10s0.20s0.30s0.40s0.50s0.60s0.70s0.80s0.90s

Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.

frames

Console

Nothing logged yet.

Expected console output

neg · delay -500 · active 1000 · ends at 500
frac · delay 0 · active 1500 · ends at 1500
alt · delay 0 · active 2000 · ends at 2000
zero · delay 0 · active 0 · ends at 0

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Try to move a box after `forwards`

In "The four fill modes" add setTimeout(() => { document.querySelector("#forwards .box").style.transform = "translateX(0)"; }, 3000); to the script and press Run.

terminal
$ After 3 seconds, read #forwards .box
── what you'll see ──
The box stays at 160 px. Its animation is listed as `finished` on the timeline, and it is still there.
Measured on the same pattern: with the class on, computed transform stayed 160 after `style.transform` was set to 300; removing the class made it jump to 300 and `getAnimations()` became empty.

Myth vs fact

Myth

After the animation ends the element stays where it ended.

Fact

Only with forwards or both. By default it jumps back to its own style.

Myth

forwards stays at the to keyframe.

Fact

It holds the last frame that ran. With alternate and two iterations that is the from side.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Use backwards (or both) with any delay on an element that should not be visible before it starts, and with an entering animation that begins at opacity: 0. Otherwise the element flashes at full opacity for the whole delay.

  • ▸

    A negative delay is how staggered or looping effects start in the middle (a whole page of spinners offset by calc(var(--i) * -100ms)), so they do not all start in step.

  • ▸

    Finished forwards animations stay in getAnimations(). On a page with hundreds of them the list, and their effect on style computation, grows. Prefer animation-fill-mode: none and set the end state in CSS when you can.

Remember this

  1. 1

    The problem this solves: by default an animation only affects the element while it runs. After the end the element jumps back to its own style, and during a delay it sits in its own style, then jumps to the first frame. These two snaps are the most common surprise in CSS animation.

  2. 2

    Fill modes. none (default): no effect before or after. forwards: after the end, the last frame stays. backwards: during the delay, the first frame already applies. both: both. Press Replay below with a one-second delay and compare the four lanes.

  3. 3

    What "last frame" means. It is the frame of the last iteration that ran, in the direction it ran. With alternate and an even count, the last frame is the from side. With 1.5 iterations it is half way through. forwards holds that frame, not necessarily to.

  4. 4

    Direction. normal runs from from to to, reverse runs backwards, alternate goes forwards then backwards, alternate-reverse starts backwards. Easing is reversed along with the direction.

  5. 5

    Iterations and delay. animation-iteration-count can be fractional (1.5), a number, or infinite. A negative delay starts the animation part-way, as if it had already been running: -500ms on a 1 s animation starts at the middle and ends after 500 ms. A delay longer than the whole animation (-3s on a 1 s one) means it is already over when it starts.

  6. 6

    Forwards holds. A finished animation with forwards is still alive: it still overrides the element's style, so later changes to that property (from CSS or element.style) have no effect until the animation is removed.

Explain it without notes

01

What is the difference between backwards and both?

02

Where does animation-iteration-count: 1.5 end, and what does forwards hold?

03

Why does setting element.style.transform have no effect after a forwards animation?

Practice

01

A card should fade in after a 300 ms delay and stay visible. Write the CSS so it is invisible during the delay.

02

A box slides 100 px, stops, and later a script should move it to 0. What must you do first?

Done when you can

  • You can predict what an element looks like before, during and after an animation for each fill mode

  • You can start an animation part-way with a negative delay

  • You know what forwards holds with alternate or fractional iterations

  • You know a finished forwards animation still overrides inline styles