v149 · CSS · SVG · Animation

Loading Spinner

CSS path-length makes stroke-dash animations trivially portable. Set path-length: 100 once and always animate stroke-dashoffset from 100 to 0 — regardless of the actual circle circumference. No JavaScript measurement required.

Checking path-length CSS support…
Animation speed:

path-length: 100 — universal unit

path { path-length: 100; stroke-dasharray: 100; stroke-dashoffset: 100; }

path-length: 60 — same CSS, different arc

path { path-length: 60; stroke-dasharray: 60; stroke-dashoffset: 60; }

path-length: 200 — finer segments

path { path-length: 200; stroke-dasharray: 200; stroke-dashoffset: 200; }

path-length: 1 — 0→1 unit range

path { path-length: 1; stroke-dasharray: 1; stroke-dashoffset: 1; }

Multi-ring — independent path-lengths

/* outer */ path-length: 100; /* inner */ path-length: 60; /* each animates independently */

CSS custom property param

/* --pl drives path-length, dasharray & dashoffset */ --pl: 100; path-length: var(--pl); stroke-dasharray: var(--pl); stroke-dashoffset: var(--pl);
/* The key insight: set path-length in CSS (Chrome 149+)
   Then your keyframe is always the same, no matter the shape */

.spinner path {
  path-length: 100;          /* normalize the path */
  stroke-dasharray: 100;     /* full dash = full path */
  stroke-dashoffset: 100;    /* start hidden */
  animation: draw 1.4s ease-in-out infinite;
}

@keyframes draw {
  0%   { stroke-dashoffset: 100; }   /* hidden */
  50%  { stroke-dashoffset: 15; }    /* 85% visible */
  100% { stroke-dashoffset: 100; }   /* hidden again */
}

/* Before Chrome 149: required JS to measure circumference
   const circ = 2 * Math.PI * r;       e.g. 150.8 for r=24
   el.style.strokeDasharray = circ;    fragile, JS dependent */

see also

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗