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.
<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:
<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.
| Attribute | Effect |
|---|---|
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 anaria-labelwhen 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
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.
| Part | Colour on background | Light | Dark | High contrast | Needs |
|---|---|---|---|---|---|
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.
Keyboard and ARIA are in the Code tab.