Skip to content

Progress

Native <progress> styled with .re-progress. Set value and max for determinate; omit value for indeterminate.

Live example
<div class="stack">
  <label class="re-field">
    <span class="re-field__label">Upload (50%)</span>
    <progress class="re-progress" id="pg-50" value="50" max="100"></progress>
  </label>
  <label class="re-field">
    <span class="re-field__label">Almost done (90%)</span>
    <progress class="re-progress" id="pg-90" value="90" max="100"></progress>
  </label>
</div>
Live example
<label class="re-field">
  <span class="re-field__label">Loading…</span>
  <progress class="re-progress" id="pg-indeterminate"></progress>
</label>
Live example
<div class="stack">
  <progress class="re-progress" id="pg-sm" data-size="sm" value="60" max="100"></progress>
  <progress class="re-progress" id="pg-md" value="60" max="100"></progress>
  <progress class="re-progress" id="pg-lg" data-size="lg" value="60" max="100"></progress>
</div>
  • Semantics — native <progress> exposes role="progressbar". When value and max are set, browsers report aria-valuenow/aria-valuemax so assistive tech announces the completion percentage; omitting value (indeterminate) is conveyed as busy with no fixed value. Give each bar a visible label — the examples wrap it in a .re-field <label> (associated via for/id) so the label is announced with the value.
  • Keyboard & focus — none: <progress> is a non-interactive indicator, so it is not in the tab order and there is no focus ring. The accessible name comes from the associated label, not from focusing the element.
  • Reduced motion — the indeterminate scanning animation is effectively disabled under prefers-reduced-motion: reduce.

For broader patterns, see the accessibility guide.