animation-duration
Setting the length of time that an animation takes to complete one cycle.
Overview
| Class | Declarations |
|---|---|
animation-duration-fastest | animation-duration: var(--duration-fastest);
|
animation-duration-faster | animation-duration: var(--duration-faster);
|
animation-duration-fast | animation-duration: var(--duration-fast);
|
animation-duration-normal | animation-duration: var(--duration-normal);
|
animation-duration-slow | animation-duration: var(--duration-slow);
|
animation-duration-slower | animation-duration: var(--duration-slower);
|
animation-duration-slowest | animation-duration: var(--duration-slowest);
|
animation-duration:<duration>,<…> | animation-duration: <duration>,<…>;
|
Examples
Set animation speed
Compare the same 72px path over 500ms and one second. Duration controls one cycle, independently of delay and repetition.
@theme { @keyframes layer-slide { from { transform: translateX(24px); } to { transform: translateX(96px); } }}<!-- 500ms cycle --><div class="w:240px max-w:100%"> <p class="mb-sm font-mono font-xs text-muted">Base 0 · start 24 · end 96px</p> <div aria-hidden="true" class="h:56px p-xs outline:1px|dashed|var(--color-line-muted)"> <span id="target" class="grid place-items:center h:40px w:48px b:1px|solid|var(--color-blue-60) r-sm bg-blue-10 fg-blue-80 transform:none animation-duration-slower animation-fill-mode:forwards animation-name:layer-slide animation-timing-function:linear animation:none@print animation-play-state:paused@reduce-motion">→</span> </div></div><!-- One-second cycle --><div class="w:240px max-w:100%"> <p class="mb-sm font-mono font-xs text-muted">Base 0 · start 24 · end 96px</p> <div aria-hidden="true" class="h:56px p-xs outline:1px|dashed|var(--color-line-muted)"> <span id="target" class="grid place-items:center h:40px w:48px b:1px|solid|var(--color-blue-60) r-sm bg-blue-10 fg-blue-80 transform:none animation-duration:1s animation-fill-mode:forwards animation-name:layer-slide animation-timing-function:linear animation:none@print animation-play-state:paused@reduce-motion">→</span> </div></div>Generated CSS
@layer theme { :root, :host { --duration-slower: .5s }}@layer utilities { .animation-duration-slower { animation-duration: var(--duration-slower) }}Use a duration token or a nonnegative CSS time. At 250ms the first marker is halfway through its cycle; the second is one quarter through.
Slow down looping motion
Compare one-second and three-second rotations with the same linear timing and infinite count.
<!-- One-second loop --><div class="flex items-center gap-md p-sm"> <svg id="target" aria-hidden="true" width="48" height="48" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" class="text-blue animation-duration:1s animation-iteration-count:infinite animation-name:rotate animation-timing-function:linear animation:none@print animation-play-state:paused@reduce-motion"> <circle cx="24" cy="24" r="17" opacity=".25" /> <path d="M24 8v16h12 M19 13l5-5 5 5" /> </svg> <span class="font-sm">One-second loop</span></div><!-- Three-second loop --><div class="flex items-center gap-md p-sm"> <svg id="target" aria-hidden="true" width="48" height="48" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" class="text-blue animation-duration:3s animation-iteration-count:infinite animation-name:rotate animation-timing-function:linear animation:none@print animation-play-state:paused@reduce-motion"> <circle cx="24" cy="24" r="17" opacity=".25" /> <path d="M24 8v16h12 M19 13l5-5 5 5" /> </svg> <span class="font-sm">Three-second loop</span></div>Longer duration lowers the steady angular speed. Keep progress text separate from decoration and provide a way to pause continuous motion.
Remove animation in static output
Compare a one-second animation with zero duration. Both use forwards fill; the zero-duration specimen immediately retains the ending keyframe.
@theme { @keyframes layer-slide { from { transform: translateX(24px); } to { transform: translateX(96px); } }}<!-- One second · retains end --><div class="w:240px max-w:100%"> <p class="mb-sm font-mono font-xs text-muted">Base 0 · start 24 · end 96px</p> <div aria-hidden="true" class="h:56px p-xs outline:1px|dashed|var(--color-line-muted)"> <span id="target" class="grid place-items:center h:40px w:48px b:1px|solid|var(--color-blue-60) r-sm bg-blue-10 fg-blue-80 transform:none animation-duration:1s animation-fill-mode:forwards animation-name:layer-slide animation-timing-function:linear animation:none@print animation-play-state:paused@reduce-motion">→</span> </div></div><!-- Zero duration · immediate end --><div class="w:240px max-w:100%"> <p class="mb-sm font-mono font-xs text-muted">Base 0 · start 24 · end 96px</p> <div aria-hidden="true" class="h:56px p-xs outline:1px|dashed|var(--color-line-muted)"> <span id="target" class="grid place-items:center h:40px w:48px b:1px|solid|var(--color-blue-60) r-sm bg-blue-10 fg-blue-80 transform:none animation-duration:0ms animation-fill-mode:forwards animation-name:layer-slide animation-timing-function:linear animation:none@print animation-play-state:paused@reduce-motion">→</span> </div></div>Zero duration is not the same as animation:none: fill can still apply a keyframe and start/end events can still occur. These snippets remove the animation in print, which restores the ordinary 0px position.
Apply conditionally
Resize before replaying to switch from a 500ms cycle to one second at sm. The path and linear easing stay fixed.
@theme { @keyframes layer-slide { from { transform: translateX(24px); } to { transform: translateX(96px); } }}<!-- 500ms → one second at sm --><div class="w:240px max-w:100%"> <p class="mb-sm font-mono font-xs text-muted">Base 0 · start 24 · end 96px</p> <div aria-hidden="true" class="h:56px p-xs outline:1px|dashed|var(--color-line-muted)"> <span id="target" class="grid place-items:center h:40px w:48px b:1px|solid|var(--color-blue-60) r-sm bg-blue-10 fg-blue-80 transform:none animation-duration-slower animation-fill-mode:forwards animation-name:layer-slide animation-timing-function:linear animation:none@print animation-play-state:paused@reduce-motion animation-duration:1s@sm">→</span> </div></div>Changing duration can update the phase of an existing animation. Replay makes the selected cycle length easy to compare from its start.