Progress
Progress — how far a task has come, on a track.
Beta · Feedback and status · packages/css/src/components/progress.css
.pui-progress · --pui-progress-value · __row __caption __label __track __indicator. No indeterminate — that is Spinner.
Sizes across, states down.
What it is for
Section titled “What it is for”- Value: 0 · 25 · 50 · 75 · 100 — the indicator’s share of the track; between the steps, resize the indicator on the instance (scale constraints keep the share when the bar stretches)
- Has label + Caption / Label: a row above the track — what is happening at the left (‘Uploading…’), the number at the right (‘50%’), 12px
- One height, 8; a stretched instance keeps it
- No indeterminate state: a task without a known share shows Spinner
Use when a task has a known share done — an upload, an import, a generation with steps, a questionnaire’s position (step n of m).
Do not use when the share is unknown (Spinner); for a value the user sets (Slider); for a score or a share of a total that is not a task (a KPI tile, a chart).
Relates to Spinner, Skeleton, Slider, Questionnaire, Stepper, KPI tile.
Anti-patterns a bar that moves backwards · a percentage without its caption on a screen with two bars · a gradient fill · a bar thinner than 8 as a decoration · a fill changed on the instance.
Keywords: progress, progress bar, upload, percent, loading, indicator
Figma — page Spinner, Skeleton & Progress: Progress (5 variants)
shadcn: progress
The markup — copy this
Section titled “The markup — copy this”The class, the parts, and nothing that is not in the package. The same block opens progress.css.
<div class="pui-progress" role="progressbar" aria-label="Uploading" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="--pui-progress-value: 50%"> <div class="pui-progress__row"><span class="pui-progress__caption">Uploading…</span><span class="pui-progress__label">50%</span></div> <div class="pui-progress__track"><div class="pui-progress__indicator"></div></div></div>The modifiers
Section titled “The modifiers”| What it is | Note | |
|---|---|---|
| Value | --pui-progress-value on the block (a percentage); the indicator’s width follows it | — |
Accessibility — measured, not assumed
Section titled “Accessibility — measured, not assumed”Every number here is measured on the rendered component: contrast (npm run contrast:render), the focus ring (npm run focus) and the keyboard (npm run keyboard). The floors are principle 12’s.
Contrast
Section titled “Contrast”| ink on ground | reads | floor | the matrix calls it | |
|---|---|---|---|---|
#544d4d on #ffffff |
8.24 | 4.5 | text.muted on surface.page (promised) | ok |
#0b0202 on #ffffff |
20.51 | 4.5 | text.default on surface.page (promised) | ok |
2 distinct pair(s) rendered, 0 that axe calls a violation.
The focus ring
Section titled “The focus ring”Nothing in this component takes focus.
Keyboard
Section titled “Keyboard”Nothing in this component claims an ARIA role with a keyboard contract; its controls are ordinary ones and the browser already gives them their keys.
Tab order across the whole library is document order over 344 stops, and Shift+Tab is its exact reverse — no keyboard trap anywhere (WCAG 2.1.2).
Pepper UI v1.5.0
The Mobupps design system. 386 tokens, 88 components, 65 pages in the workshop — every page of this site generated from the repository, so nothing here is typed twice.