Shots in this scene
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.
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
Read the end positions
In the last example Replay and step to the end. The
1.5 iterationsbox rests half way (70 px), thealternatebox is back at 10 px (its last iteration ran backwards), the0sbox is already at 130 px, and the-500msbox started at 70 px. - 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.
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.
Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.
Console
Nothing logged yet.All four have fill `both`. Compare where each box finishes.
Nothing is moving yet. Hover, click or scroll the page: every animation it starts shows up here as a track.
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 0Break 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.
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(orboth) with any delay on an element that should not be visible before it starts, and with an entering animation that begins atopacity: 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
forwardsanimations stay ingetAnimations(). On a page with hundreds of them the list, and their effect on style computation, grows. Preferanimation-fill-mode: noneand set the end state in CSS when you can.
Remember this
- 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
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
What "last frame" means. It is the frame of the last iteration that ran, in the direction it ran. With
alternateand an even count, the last frame is thefromside. With1.5iterations it is half way through.forwardsholds that frame, not necessarilyto. - 4
Direction.
normalruns fromfromtoto,reverseruns backwards,alternategoes forwards then backwards,alternate-reversestarts backwards. Easing is reversed along with the direction. - 5
Iterations and delay.
animation-iteration-countcan be fractional (1.5), a number, orinfinite. A negative delay starts the animation part-way, as if it had already been running:-500mson a 1 s animation starts at the middle and ends after 500 ms. A delay longer than the whole animation (-3son a 1 s one) means it is already over when it starts. - 6
Forwards holds. A finished animation with
forwardsis still alive: it still overrides the element's style, so later changes to that property (from CSS orelement.style) have no effect until the animation is removed.
Explain it without notes
What is the difference between backwards and both?
Where does animation-iteration-count: 1.5 end, and what does forwards hold?
Why does setting element.style.transform have no effect after a forwards animation?
Practice
A card should fade in after a 300 ms delay and stay visible. Write the CSS so it is invisible during the delay.
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
forwardsholds with alternate or fractional iterationsYou know a finished forwards animation still overrides inline styles