Skip to content

Stacked circular progress bars — CSS multi-ring example

If you’ve ever opened the Apple Health app or any modern fitness tracker, you know what stacked progress rings look like: three concentric circles, each tracking a different metric, sharing the same center. The visual is so good because it answers three questions in one glance and gives the user a single point of focus instead of three separate widgets.

This example places three <o-progress> rings on three different orbits (orbit-2, orbit-3, orbit-4) — each at a different value, each with its own color. The black background is doing real work: it makes the neon colors pop the way they do on a smartwatch.

How it works

  • Three orbits, three rings. orbit-2 is the innermost, orbit-4 the outermost. Each hosts a single <o-progress> element. Because they share the same gravity-spot, all three rings are perfectly concentric without any positioning math.
  • shrink-10 on each progress thins each ring slightly relative to its orbit so the rings don’t touch — the small gap between them is what makes the design feel airy instead of cluttered.
  • Colors via CSS variables keep the markup clean. Each ring has a single class (cyan, green, red) that just sets --o-fill. Swap any of those three lines and the corresponding ring re-themes instantly.
  • Black bigbang background is non-negotiable for this look — the contrast against neon fills is what sells the smartwatch aesthetic. A white or transparent background drains the colors.

Customization

Bind to real metrics by setting value from JS:

document.querySelectorAll('o-progress').forEach((ring, i) => {
const metrics = [steps, calories, exerciseMinutes];
const goals = [10000, 600, 30];
ring.setAttribute('value', Math.min(100, (metrics[i] / goals[i]) * 100));
});

Add labels in the center with a satellite at orbit-0:

<div class="orbit-0">
<div class="satellite">
<div class="capsule">8.2k</div>
</div>
</div>

Add a fourth ring by adding another orbit-X parent — Orbit handles the spacing automatically.

Use this in your project

Install Orbit CSS and adapt the markup above.