Progress bar
A progress bar shows how far a task has gone on a known scale. It only reports progress; it can't be focused or clicked.
<tk-progress-bar value="60" show-value label="Uploading report.pdf"></tk-progress-bar>
Anatomy
| Part | What it is |
|---|---|
tk-progress-bar |
the element; role="progressbar", never focusable |
| track | the full-width rail: the whole scale |
| fill | the done part, from the start edge |
| readout | the value, beside or above the track, with show-value |
| default slot | your own label or status text; replaces the readout |
Variants
<tk-progress-bar value="60" show-value label="Import"></tk-progress-bar> <tk-progress-bar value="100" intent="success" label="Import">Import complete</tk-progress-bar> <tk-progress-bar value="40" intent="error" label="Import">Import failed. Try again.</tk-progress-bar>
accent(default): ordinary progress, including at 100%.success: a finished task, with text that says so.error: a failed task, with text that says what went wrong.
The bar never turns green on its own at 100%. Set intent yourself, and always add text;
color alone doesn't tell everyone.
Segments
segments splits the track into equal cells. It's only a look: the value stays continuous,
and the cells have no labels and no keyboard steps.
<tk-progress-bar value="3" max="5" segments="5" show-value value-format="fraction" label="Profile setup"></tk-progress-bar>
Sizes
<tk-progress-bar value="60" size="small" label="Uploading photos"></tk-progress-bar> <tk-progress-bar value="60" label="Uploading photos"></tk-progress-bar>
size |
Thickness |
|---|---|
small |
4px (space-4) |
medium (default) |
8px (space-8) |
States
<tk-progress-bar label="Loading messages"></tk-progress-bar>
- Determinate: set
value. It's clamped betweenmin(0) andmax(100). - Indeterminate: leave out
value. A segment sweeps the track and no number shows; a slot label such as "Loading messages" still can.segmentsis ignored.
Value and readout
<tk-progress-bar value="18" max="25" show-value value-format="fraction" label="Files uploaded"></tk-progress-bar> <tk-progress-bar value="72" show-value value-position="top" label="Exporting video"></tk-progress-bar>
show-valueshows the value:72%by default, or18 of 25withvalue-format="fraction".value-position="top"puts it above the track; the default is beside it. It never sits on the fill.- Text in the default slot replaces the readout.
When to use
- Use a progress bar when you know how much work there is: an upload, an import, a form with steps.
- Use it without a value when a linear task runs but you can't measure it.
- Use a
Progress ring in a small or square space, or to show the value in the middle. - Use a
Spinner for a short wait with no scale, such as a button or a panel loading. - Don't use it for numbered steps the user moves between, or for a static measurement such as disk space.
Content
- Name the task in
label: "Uploading report.pdf", not "Progress". - In a status, say what's happening: "Uploading 18 of 25 files". On failure, say what failed and what to do.
More in
Do / Don't
| ✅ Do | ❌ Don't |
|---|---|
Pair intent with text |
Rely on color alone for success or failure |
| Keep the fill color at 100% | Switch to green automatically on completion |
Leave out value when you can't measure |
Fake a value to look determinate |
| Use a spinner for a short wait with no scale | Use an indeterminate bar for a button |
| Put the value beside or above | Put the value on the fill |
| Use segments to show a task in equal parts | Build a numbered step flow from segments |
Related
Progress ring : the same value as a circle.Spinner : a wait with no scale.Skeleton : a placeholder in the shape of content that's loading.
API
Attributes
| Attribute | Type | Default | What it does |
|---|---|---|---|
value |
number | unset | position on the scale; unset makes it indeterminate |
min |
number | 0 |
start of the scale |
max |
number | 100 |
end of the scale |
intent |
accent | success | error |
accent |
fill color; pair it with text |
show-value |
boolean | false |
shows the value |
value-format |
percent | fraction |
percent |
72% or 18 of 25 |
value-position |
end | top |
end |
readout beside or above the track |
size |
small | medium |
medium |
4px or 8px thick |
segments |
number | 0 |
2 or more splits the track into cells |
label |
string | unset | accessible name |
Slots
| Slot | Content |
|---|---|
| default | a label or status; replaces the readout and is announced politely |
Events
None.
Tokens
| Part | Token |
|---|---|
| track | surface/sunken |
| fill | fill/accent, fill/success, fill/error |
| readout | text/secondary, Label Small (font-size-sm, font-weight-medium) |
| corners | radius-full on the track, fill, and every cell |
Values per theme:
Accessibility
Built in:
role="progressbar"witharia-valuemin,aria-valuemax,aria-valuenow, andaria-valuetext(the readout text). Indeterminate leaves outaria-valuenow.- Slot text sits in a polite live region, so a status or error is announced without moving focus.
- Never focusable and never a Tab stop.
- With reduced motion, the fill jumps to its new value and the sweep stands still.
Your part:
- Name every bar with
label,aria-label, oraria-labelledby. An unnamed bar warns in the console. - Pair
successanderrorwith text.
Contrast limits
- Accent fill against the track: at least 3:1 with the blue, indigo, purple, and black
primary colors. In light it falls to 1.65–2.63:1 with orange, green, mint, teal, brown,
and gray; in high contrast to 2.02–2.94:1 with orange, green, mint, teal, and gray. Dark
holds 3:1 with every color. Where it falls short, turn on
show-valueor put the value in text. - Success and error fills: at least 3.50:1 in every theme.