material-circular-progress

MD3 circular progress indicator — determinate / indeterminate × flat / wavy. Configurable size + thickness; spec range 24–240dp.

Determinate — flat

Active arc starts at 12 o'clock and sweeps clockwise to value%. Default 40dp diameter / 4dp stroke; the 8dp sample is 44dp diameter.

40 / 4dp · 25%
40 / 4dp · 60%
44 / 8dp · 60%
64 / 4dp · 80%
120 / 4dp · 50%

Determinate — wavy

Active arc oscillates radially with 1.6dp amplitude and ~15dp wavelength along the arc length. Wavy diameters are slightly larger to give the wave room: 48dp (4dp) / 52dp (8dp). The wave's phase animates so it appears to flow along the arc.

48 / 4dp · 60%
52 / 8dp · 80%
96 / 4dp · 40%
160 / 4dp · 65%

Indeterminate

Outer rotation (~2s) plus a sweep that grows and shrinks (~1.3s); the offset cycle keeps the motion lively. For short indeterminate processes (under 5s), prefer material-loading-indicator instead.

40 / 4dp flat
64 / 8dp flat
48 / 4dp wavy
96 / 4dp wavy
160 / 4dp wavy

In a button

Per spec § In buttons: replace the icon/label with the indicator while an action is pending. At very small sizes (≤24dp), use the flat shape — the wavy detail isn't visible.

Saving… Submitting Refreshing

Live demo — determinate slider

Drag to drive value on flat and wavy variants simultaneously.

value = 35

Reduced motion + paused

prefers-reduced-motion: reduce freezes the animations. Toggle Rendering ▸ Emulate prefers-reduced-motion in DevTools. paused attribute halts the rAF loop on demand.

Toggle paused running
Sample usage
<!-- Determinate flat (default 40dp / 4dp stroke) -->
<material-circular-progress value="60" label="Saving…"></material-circular-progress>

<!-- Determinate wavy, larger -->
<material-circular-progress value="60" wavy size="96" label="Saving…"></material-circular-progress>

<!-- Indeterminate (omit value) -->
<material-circular-progress label="Loading"></material-circular-progress>

<!-- In a button (small, flat) -->
<material-button variant="filled">
  <material-circular-progress size="20" label="Saving"></material-circular-progress>
  Saving…
</material-button>

<!-- Pause animation -->
<material-circular-progress wavy paused></material-circular-progress>