Skip to content

CSS knob with progress bar — Orbit example

A rotary knob with a built-in progress arc is the standard control on synthesizers, mixing desks and any UI where the user needs to feel like they’re turning something. The progress arc serves a real purpose — it answers the question “how much?” without forcing the user to look up at a separate readout.

This example builds the knob body from a textured background, places ten tick marks around it, and overlays an <o-progress> arc that visually fills as the value rises. Orbit renders the SVG progress arc and maintains the layout. The extra JavaScript in the third tab generates the tick marks for brevity.

Examples include the current Orbit stylesheet and runtime. Get both files for your project.

  • from-215 range-290 is the trick that gives the knob its iconic shape: it sweeps a 290° arc starting at 215° (lower-left), leaving a 70° gap at the bottom — exactly where you’d grip a real knob.
  • Three concentric orbits are stacked: orbit-2 for the textured body, orbit-3 shrink-10 for the tick marks, and orbit-3 shrink-60 for the progress arc. Stacking them on the same parent gravity-spot keeps everything centered automatically.
  • The center LED is a satellite at orbit-0 (the dead center) with a radial gradient background, so it looks like a glowing indicator. Swap the gradient color and you’ve got a power LED for any color you want.
  • <o-progress value="50" shape="circle"> is the progress arc itself — bind the value attribute to your state and it animates by setting CSS variables under the hood.

Make the knob respond to a real value:

<o-progress value="75" shape="circle" class="shrink-80 outer-orbit"></o-progress>

Change the progress color to amber for a warning state:

o-progress { --o-fill: var(--o-orange) }

Add a pointer indicator by placing a vector on the same orbit as the progress, rotated to the current value:

<div class="orbit-3 shrink-60">
<div class="vector grow-1x outer-orbit angle-200 pointer"></div>
</div>

Install Orbit and copy the markup above.