Motion

animation-delay

Setting when an animation starts or which phase it starts from.

Overview

ClassDeclarations
animation-delay:<time>,<…>animation-delay: <time>,<…>;

Examples

Delay animation start

Compare no delay with a 600ms wait before the same one-second movement. Press Replay to start both timelines together.

Delay animation start
animation-delay: Delay animation start controls
Play opts into the actual CSS animation. Pause retains its time; Replay restarts even a finished one-shot. Readouts show native timeline time and progress, including delay and fill.
index.css
@theme {  @keyframes layer-slide {    from { transform: translateX(24px); }    to { transform: translateX(96px); }  }}
<!-- No delay --><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-delay:0ms 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>
<!-- 600ms delay --><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-delay:600ms 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 utilities {  .animation-delay\:600ms {    animation-delay: 600ms  }}

A positive delay postpones the first cycle, not every repetition. Without backwards fill, the delayed marker stays at its ordinary position (0px) until its first keyframe (24px) applies.

Offset looping animations

Use a negative delay to begin partway through an animation. Both hands have a two-second cycle; the second starts 500ms ahead.

Offset looping animations
animation-delay: Offset looping animations controls
Play opts into the actual CSS animation. Pause retains its time; Replay restarts even a finished one-shot. Readouts show native timeline time and progress, including delay and fill.
<!-- No offset --><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-delay:0ms           animation-duration:2s           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">No offset</span></div>
<!-- 500ms ahead --><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-delay:-500ms           animation-duration:2s           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">500ms ahead</span></div>

The negative delay changes the starting phase, not the duration. After 500ms, the first hand reaches the second hand’s original quarter-turn position.

Stagger a list

Give each decorative child its own animation and delay. The 200ms offsets overlap these 800ms entrances instead of waiting for each preceding entrance to finish.

Stagger a list
animation-delay: Stagger a list controls
Play opts into the actual CSS animation. Pause retains its time; Replay restarts even a finished one-shot. Readouts show native timeline time and progress, including delay and fill.
<!-- Three independent entrance timelines --><ul class="grid gap-sm m:0 p-sm list-style:none">  <li class="flex items-center gap-sm font-sm">    <span aria-hidden="true"      class="inline-block h:32px w:64px             b:1px|solid|var(--color-blue-60) r-sm bg-blue-10             animation:fade|var(--duration-slowest)|linear|both             animation-delay:0ms animation:none@print             animation-play-state:paused@reduce-motion"></span>    <span>Item 1 · 0ms</span>  </li>  <li class="flex items-center gap-sm font-sm">    <span aria-hidden="true"      class="inline-block h:32px w:64px             b:1px|solid|var(--color-blue-60) r-sm bg-blue-10             animation:fade|var(--duration-slowest)|linear|both             animation-delay:200ms animation:none@print             animation-play-state:paused@reduce-motion"></span>    <span>Item 2 · 200ms</span>  </li>  <li class="flex items-center gap-sm font-sm">    <span id="target" aria-hidden="true"      class="inline-block h:32px w:64px             b:1px|solid|var(--color-blue-60) r-sm bg-blue-10             animation:fade|var(--duration-slowest)|linear|both             animation-delay:400ms animation:none@print             animation-play-state:paused@reduce-motion"></span>    <span>Item 3 · 400ms</span>  </li></ul>

Animation properties are not inherited. Backwards fill, included in both, keeps each waiting marker at the fade keyframe’s transparent start; the item labels remain visible.

Use duration tokens

Define a duration token for a shared waiting interval. This example resolves stagger to 120ms and uses the preset fade keyframes.

Use duration tokens
animation-delay: Use duration tokens controls
Play opts into the actual CSS animation. Pause retains its time; Replay restarts even a finished one-shot. Readouts show native timeline time and progress, including delay and fill.
index.css
@theme {  --duration-stagger: 120ms;}
<!-- 120ms delayed marker --><div class="flex items-center gap-md p-sm">  <span id="target" aria-hidden="true"    class="block h:40px w:64px b:1px|solid|var(--color-blue-60) r-sm           bg-blue-10 opacity:1 animation-duration:1s           animation-fill-mode:both animation-name:fade           animation-timing-function-smooth           animation:none@print           animation-play-state:paused@reduce-motion           animation-delay-stagger"></span>  <span class="font-sm">120ms delayed marker</span></div>

The duration and delay can use the same namespace independently. This delay is 120ms; the animation still takes one second after it begins.

Apply conditionally

Resize before replaying. The marker waits 600ms below sm and starts immediately at sm; its one-second movement stays the same.

Apply conditionally
animation-delay: Apply conditionally controls
Play opts into the actual CSS animation. Pause retains its time; Replay restarts even a finished one-shot. Readouts show native timeline time and progress, including delay and fill.
index.css
@theme {  @keyframes layer-slide {    from { transform: translateX(24px); }    to { transform: translateX(96px); }  }}
<!-- 600ms → no delay 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-delay:600ms animation-duration:1s             animation-fill-mode:forwards             animation-name:layer-slide             animation-timing-function:linear             animation:none@print             animation-play-state:paused@reduce-motion             animation-delay:0ms@sm">→</span>  </div></div>

Changing a delay while an animation already exists can move its current phase. Replay compares the newly selected value from time zero.



© 2026 Aoyue Design LLC.MIT License
Trademark Policy