Skip to content

Progress spinner

<aparte-progress-spinner>

AparteProgressSpinner

Circular progress spinner web component.

  • Indeterminate (no value attribute): continuous rotation animation
  • Determinate (value="0–100"): fills the arc proportionally

The ABSENCE of the attribute is what selects indeterminate, so value="" is not “unknown progress” — it parses to 0, i.e. an empty determinate arc. value is clamped to 0–100 and anything non-numeric reads as 0; nothing throws.

It renders its own SVG into itself on connect and on every value change, so it takes no children: whatever you put inside is overwritten. The SVG is aria-hidden and the ARIA lives on the host (role="progressbar", aria-valuemin/aria-valuemax, plus aria-valuenow only when determinate) — there is no accessible NAME, so give the element an aria-label unless the surrounding text already says what is loading.

It draws an arc; it does not manage a loading lifecycle — no delay before appearing, no timeout, no label, no live announcement. Under prefers-reduced-motion: reduce the rotation stops (aparte.css scopes that rule to the library’s own elements), which is the other reason the indeterminate arc must not be the only signal that work is in flight.

Width Open in a tab
The real element, in its own document so this site's CSS cannot reach it. It renders the same example printed below — every framework mounts this same element, so the rendering is what you get in all five; the code is what changes.
<!-- Omit `value` for the indeterminate spin; set it to show real progress. -->
<aparte-progress-spinner></aparte-progress-spinner>
<aparte-progress-spinner value="62"></aparte-progress-spinner>
AttributeDescription
valueProgress percentage 0–100 (omit for indeterminate)

Override any of these on :root, on a subtree, or on one instance — custom properties inherit downward. Some are this element’s own; others are site-wide tokens that also style it, and overriding one of those at :root moves everything that reads it. The full set is in the CSS variables reference.

VariableDefaultDescription
--aparte-spinner-sizevar(--aparte-spinner-size-md)Width and height of the element; the SVG fills it.
--aparte-spinner-colorcurrentColorStroke of the filled (progress) arc.
--aparte-spinner-trackvar(--aparte-border-control)Stroke of the track arc behind it.

The element is the same object everywhere — the tag does not change. What changes is how an attribute is written and how an event reaches you.

<aparte-progress-spinner value=""></aparte-progress-spinner>

Installation and the framework-specific traps: React · Vue · Svelte · Angular.