Skip to content

Progress

hc-progress is applied to a standard <progress> element. The native element retains its ARIA role="progressbar" semantics and the value / max attribute pair; only the visual chrome is replaced via appearance: none and per-vendor pseudo-elements.

Set value and (optionally) max. The browser computes the percentage automatically.

The fill transitions smoothly when value changes — htmx swaps, JS updates, etc.

Omit value for the “unknown duration” state. A muted gradient slides across the track at a steady cadence.

The slide animation respects prefers-reduced-motion: reduce — when the user has opted out of motion, the track displays a static centred gradient instead.

data-variant accepts success, warning, and error for non-default fill colors.

data-size accepts sm, md (default), and lg.

A <progress> is a normal DOM node — htmx can swap it like any other element. Pair with a polling or SSE pattern to show server-side progress:

<progress
class="hc-progress"
value="0" max="100"
aria-label="Importing"
data-hx-get="/imports/42/progress"
data-hx-trigger="every 500ms"
data-hx-swap="outerHTML">
</progress>

The server returns an updated <progress class="hc-progress" value="N" max="100">; the fill animates from the previous value to the new one.

  • Always give the element an accessible name — either an aria-label or a wrapping <label for> element. Without one, screen readers announce “progress bar” without context.
  • value and max carry the percentage. There is no need to also set aria-valuenow / aria-valuemax; the browser maps the attributes to the accessibility tree automatically.
  • For long-running tasks (over a few seconds), pair the progress bar with a status text that periodically updates. A bare bar alone is hard to interpret.
  • The indeterminate animation suppresses itself for prefers-reduced-motion: reduce users.

Component tokens (in component.tokens.json):

Token pathPurpose
progress.heightTrack height.
progress.radiusTrack corner radius.
progress.bgTrack background.
progress.fillDefault fill color (action.primary).
progress.success-fill / warning-fill / error-fillVariant fills.
progress.transition-durationFill animation when value changes.
progress.indeterminate-durationSlide-cycle duration when no value.
progress.sm.height / lg.heightSize variants.
Show the generated CSS variables
--hc-progress-height | -radius | -bg | -fill
--hc-progress-success-fill | -warning-fill | -error-fill
--hc-progress-transition-duration | -indeterminate-duration
--hc-progress-sm-height | -lg-height
  • Spinner — when the duration is too short or too unknown to merit a bar.
  • Alert — pairs well with a progress bar in an “importing… 60%” status row.