progress-ring

CSS-only circular progress indicator with size and color variants.

Overview

The <progress-ring> element displays a circular progress indicator using pure CSS (conic-gradient + mask). Set the progress value via the --progress custom property (0–100).

<progress-ring style="--progress: 75" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"> <span>75%</span> </progress-ring>

Attributes

Attribute Values Default Description
data-size xs, s, m, l, xl m Ring size.
data-variant success, warning, error interactive Color variant.
data-indeterminate boolean Shows a spinning indeterminate animation.

Sizes

60% 60% 60%
<progress-ring data-size="xs" style="--progress: 60" role="progressbar" aria-valuenow="60"></progress-ring> <progress-ring data-size="s" style="--progress: 60" role="progressbar" aria-valuenow="60"></progress-ring> <progress-ring data-size="m" style="--progress: 60" role="progressbar" aria-valuenow="60"><span>60%</span></progress-ring> <progress-ring data-size="l" style="--progress: 60" role="progressbar" aria-valuenow="60"><span>60%</span></progress-ring> <progress-ring data-size="xl" style="--progress: 60" role="progressbar" aria-valuenow="60"><span>60%</span></progress-ring>

Color Variants

Done 45% 15%
<progress-ring data-variant="success" style="--progress: 100" data-size="l"><span>Done</span></progress-ring> <progress-ring data-variant="warning" style="--progress: 45" data-size="l"><span>45%</span></progress-ring> <progress-ring data-variant="error" style="--progress: 15" data-size="l"><span>15%</span></progress-ring>

Indeterminate

Add data-indeterminate for a spinning animation when the progress value is unknown.

<progress-ring data-indeterminate data-size="l" role="progressbar" aria-label="Loading"></progress-ring>

Updating with JavaScript

Update the --progress property dynamically. Remember to also update aria-valuenow.

const ring = document.querySelector('progress-ring'); ring.style.setProperty('--progress', '85'); ring.setAttribute('aria-valuenow', '85');

Custom Properties

Property Default Description
--progress 0 Progress value (0–100).
--progress-ring-size 4em Ring diameter.
--progress-ring-width 0.35em Ring track thickness.
--progress-ring-color interactive Filled arc color.
--progress-ring-track 15% of color Background track color.
progress-ring { --progress-ring-size: 6em; --progress-ring-width: 0.5em; --progress-ring-color: oklch(55% 0.2 260); }

Accessibility

  • Add role="progressbar" with aria-valuenow, aria-valuemin, aria-valuemax for determinate progress.
  • For indeterminate, add aria-label="Loading" instead.
  • Animation slows under prefers-reduced-motion: reduce.
  • CSS-only: works without JavaScript.

Related Elements