Motion

animation-iteration-count

Setting the number of times an animation should be played.

Overview

ClassDeclarations
animation-iteration-count:infiniteanimation-iteration-count: infinite;
animation-iteration-count:<value>animation-iteration-count: <value>;

Examples

Loop animation

Use infinite to repeat the two-second rotation until its animation is removed or paused.

Loop animation
animation-iteration-count: Loop animation 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.
<!-- Continuous indicator --><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: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">Continuous indicator</span></div>
Generated CSS
@layer utilities {  .animation-iteration-count\:infinite {    animation-iteration-count: infinite  }}

A positive delay applies before the first cycle only. Infinite animation has no natural ending phase for forwards fill; keep a pause control available.

Specify a number of iterations

Compare three complete cycles with two and a half cycles. Both use one-second linear keyframes and forwards fill.

Specify a number of iterations
animation-iteration-count: Specify a number of iterations 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); }  }}
<!-- Three cycles · ends at 96px --><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-iteration-count:3             animation-name:layer-slide             animation-timing-function:linear             animation:none@print             animation-play-state:paused@reduce-motion">→</span>  </div></div>
<!-- 2.5 cycles · ends at 60px --><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-iteration-count:2.5             animation-name:layer-slide             animation-timing-function:linear             animation:none@print             animation-play-state:paused@reduce-motion">→</span>  </div></div>

The active duration is duration × count, excluding delay and paused time. Fractional counts stop within the last cycle; negative counts are invalid.

Pair with fill mode

Use a finite count with forwards fill. With alternate direction, an even count ends back at the first keyframe.

Pair with fill mode
animation-iteration-count: Pair with fill mode 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); }  }}
<!-- Two alternate cycles · ends at 24px --><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-direction:alternate             animation-duration:1s             animation-fill-mode:forwards             animation-iteration-count:2             animation-name:layer-slide             animation-timing-function:linear             animation:none@print             animation-play-state:paused@reduce-motion">→</span>  </div></div>

The second cycle runs backward. The retained value is therefore 24px, not 96px; fill follows the actual final iteration.

Apply conditionally

Resize before replaying to run one cycle below sm or three cycles at sm.

Apply conditionally
animation-iteration-count: 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); }  }}
<!-- One → three cycles 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:1s             animation-fill-mode:forwards             animation-iteration-count:1             animation-name:layer-slide             animation-timing-function:linear             animation:none@print             animation-play-state:paused@reduce-motion             animation-iteration-count:3@sm">→</span>  </div></div>

Duration remains one second per cycle. Changing the count can extend or shorten an existing animation; Replay restarts the selected sequence.



© 2026 Aoyue Design LLC.MIT License
Trademark Policy