Skip to main content

Core · Feedback and status

Progress

Shows how far a task that takes time has got, with the native progress element.

Example

Two progress bars: an upload at 25 percent and a build at 67 percent.

Known issues

None known.

Code

Copy the markup

A bare progress needs no class: it has the size of the component and the brand color in its fill.

HTML
<label for="upload">Uploading report.pdf</label>
<progress id="upload" value="25" max="100">25%</progress>

.luz-progress draws the track and the fill itself. With the class:

HTML
<label for="upload">Uploading report.pdf</label>
<progress class="luz-progress" id="upload" value="25" max="100">25%</progress>

Variants and options

One class. The state comes from the native attributes.

AttributeEffect
value and max
How much is done; max is 1 if you leave it out
no value
Indeterminate: the task is running but its length is unknown

How it works

The native <progress> element, styled by components/progress.css: an 8 px bar, full width, with the brand colour as the fill and a 1 px edge in the field border colour, so the whole length shows on any surface.

  • The browser exposes the role and the value to assistive technology.
  • In Chromium and WebKit browsers the fill slides to a new value; under reduced motion it jumps.
  • In forced colors the bar keeps a border and draws the fill in the system highlight colour.

Without JavaScript

The bar shows the value in the markup. Moving it needs your script, which sets value.

Keyboard and ARIA

A progress bar is not interactive and takes no focus.

  • Name it with a <label>, or an aria-label when no label is shown.
  • Screen readers do not announce every change. Announce the start and the end in a polite live region (role="status").

Contrast and focus are in the Design tab.

Design

When to use

Use a progress bar for a task that takes more than a few seconds, such as an upload or a build.

When not to use

Do not use a progress bar for a value that is not a task.

  • For a measure in a known range, such as storage used, use a meter.
  • Do not use it as decoration.

Do and don't

Do A task with an end, named with the figure: “Uploading report.pdf, 25%”.
Don't Storage used is a measure, not a task: a progress bar suggests it will finish. Use a meter.

Writing the content

Say what is happening, not just the number: "Uploading report.pdf".

  • Put the figure in the name or next to the bar: "Upload, 25%".
  • When it ends, say so: "Upload complete".

Contrast and focus

The done part is the brand colour on a muted track. The track has an edge in the field border colour, so you can see where the bar ends.

PartColour on backgroundLightDarkHigh contrastNeeds
Done part against the track
--luz-brand-primary on --luz-surface-muted
5.6:1
7.7:1
13.5:1
3:1
Edge of the track against the page
--luz-input-border on --luz-surface-page
3.7:1
4.2:1
21.0:1
3:1

Measured from the token values of each mode, rounded down. Needs is the WCAG 2.2 AA minimum: 4.5:1 for text, 3:1 for focus rings, borders and icons.

  • Focus: the bar takes none.
  • Not colour alone: put the figure in words next to the bar or in its name, so the value never depends on telling the two parts of the bar apart.

Tokens it uses

The 6 tokens that components/progress.css reads, by family. Each family links to its page, with the values in every mode. In Figma they are variables with the same names: see Tokens in Figma.

Radius
--luz-radius-sm
Motion
--luz-duration-slow, --luz-easing-enter

Keyboard and ARIA are in the Code tab.