Design HubStudio

11. Progress

Linear, circular, indeterminate. A small primitive set, but worth being deliberate about — the choice between a percent bar and an indeterminate sweep is the difference between "almost done" and "still alive."

Gallery

The .progress primitive ships in three sizes and four semantic colors, plus an indeterminate variant. Circular progress is rendered via SVG (no dedicated component class — the geometry varies enough per use).

Linear · 70%
Success · 45%
Warning · large · 88%
Indeterminate
Spinner · circular
70%
When to use each

Three short rules. Progress decisions overlap with the loading discussion in Empty / error / loading (Section 12) — both answer "what does the user see while waiting?"

Linear with percent — when the operation has known progress and the user wants to estimate "how much longer?" Uploads, exports, batch processing, run compilation.
Indeterminate — when the duration is unknown but the operation is still progressing. The sweep communicates "working" without a fake percentage. Don't fake progress; fake progress reads as broken when it stalls.
Spinner — short async operations on a specific control. Buttons in loading state, inline saves, field-level validation. For waits longer than 5s, switch to a progress bar with status text.
Three rules of progress — (1) never fake a percentage; if you don't know, use indeterminate. (2) Anything under 300ms shows nothing — flicker is worse than instant. (3) Anything over 10s needs status text, not just a bar.