CSS animation timing explained
Timing determines whether an animation communicates a change or merely adds delay. CSS separates timing into several properties: duration controls the length of one cycle, delay controls when it begins, and the timing function controls how progress is distributed through that cycle. Iteration, direction, and fill properties decide what happens around subsequent cycles.
Duration is only one part of perceived speed
animation-duration accepts seconds or milliseconds.
The same 400-millisecond duration can feel quick over a short
distance and abrupt over a full screen. Evaluate duration with
the final component dimensions rather than tuning a small isolated
square and assuming the result will transfer.
A duration of zero means there is no visible interpolation. This can be useful in a reduced-motion rule because the element reaches the intended state without making users wait through movement. Do not replace a short animation with a long delay: delayed controls can appear unresponsive.
Delays can be positive or negative
A positive animation-delay waits before the first
cycle. A negative delay starts immediately at a later point in
the cycle. Negative delays are particularly useful for repeated
loaders or decorative tiles because they create phase differences
without a blank initial period.
.tile:nth-child(1) { animation-delay: 0ms; }
.tile:nth-child(2) { animation-delay: -200ms; }
.tile:nth-child(3) { animation-delay: -400ms; } Select an easing function by purpose
The default ease timing accelerates and then
decelerates. linear advances at a constant rate and is suitable
for continuous rotation, progress along a known scale, or a demonstration
where each keyframe interval should receive equal time. Constant
speed often looks mechanical for panels or objects entering a
screen.
ease-out moves quickly at first and slows near
the destination, which helps an entering element feel
responsive. ease-in starts slowly and can suit an
element leaving the interface, although the slow start may make
a direct user action feel delayed. Test with actual interaction
rather than choosing an easing name by appearance alone.
Use cubic Bézier curves deliberately
cubic-bezier(x1, y1, x2, y2) defines two control
points. The x values must remain between zero and one. Y values
outside that range can create overshoot, which may be useful for
a restrained bounce but can also make text or controls difficult
to track. Keep a named design token for curves reused by many
components so motion remains consistent.
:root {
--motion-enter: cubic-bezier(0.2, 0.8, 0.2, 1);
}
.panel {
animation: panel-enter 300ms var(--motion-enter);
} Steps are discrete, not eased
steps() divides a cycle into a fixed number of jumps.
It is useful for sprite sheets, counters, or typewriter-like reveals
where intermediate frames must not be blended. Match the step
count to the number of intended frames; a mismatch can show part
of the next sprite or omit the final state.
Iteration and direction shape repeated motion
animation-iteration-count: infinite is appropriate
for a live reference demo, but it should not be the default for
every product interface. Repeated motion competes for attention
and continues using rendering resources. Prefer a finite count
for feedback that only needs to acknowledge an event.
alternate reverses every second cycle, avoiding
the jump from the last keyframe back to the first. alternate-reverse begins from the other end. Direction
changes the order of keyframes; it does not reverse the meaning
of application state.
Pause and final-state behavior
animation-play-state: paused freezes the
current progress and running resumes it. This is what the pause
button on animania detail pages controls. animation-fill-mode instead controls which keyframe
styles apply before or after playback; it does not pause a cycle.
Performance-oriented timing choices
Prefer animating transform and opacity when they can express the effect. Properties
that repeatedly change layout can cause the browser to recalculate
positions throughout the page. Avoid leaving dozens of offscreen
infinite animations running. The animania overview mounts previews
only while their cards intersect the viewport for this reason.
Next, learn how to customize an effect, review accessible motion, or compare timing visually in the CSS effect index.