Design Pattern
Progress Bar
A progress bar is a pattern for showing task progress or completion visually. Using the native progress element helps assistive technology understand the current progress correctly.
When to use / not use
Use it when
- When you want to show upload or download progress
- When you want to indicate steps completed in a form flow
- When you want to show static percentages such as skill level or completion rate
Don't use it when
- When loading is in progress but the percentage is unknown → use a spinner or skeleton
- When the data changes continuously in real time → use a meter or chart
- When the user needs to control the value directly → use a range input
Anatomy
1 Label (describes the progress)
2 Track (background bar)
3 Indicator (filled progress bar)
4 Value text (percentage display)
- Label — Clarifies what the progress refers to. Without it, the meaning is unclear
- Track — Shows the full range in the background. Maintain clear contrast with the indicator
- Indicator — Represents the current progress by width and can also signal state by color
HTML Structure
Key points
- Using the
progresselement automatically provides role andaria-valuenow - Omitting the
valueattribute creates an indeterminate state - Associate the bar with a label element or an
aria-label - Also display progress as text so users can understand it without relying on visuals alone
CSS Implementation
Styling points
- Track — Use a light background to show the full range
- Indicator — Use a sufficiently contrasting color to show progress
- Shape — Keep the border radius consistent between the track and indicator
- Animation — In indeterminate states, motion can help communicate that work is still in progress
Accessibility
WCAG 1.3.1 Info and Relationships
Associate the progress element with a label so assistive technology knows what it refers to.
WCAG 4.1.2 Name, Role, Value
Assistive technology needs to receive the current and maximum values correctly.
WCAG 4.1.3 Status Messages
If the progress changes dynamically, announce updates with aria-live.
Keyboard guidance
- A progress bar itself is not interactive, so it usually should not receive focus
- Controls related to progress, such as a cancel button, should be keyboard reachable
- Completion should be announced with
aria-live="polite"when appropriate
Live Demo
Common mistakes
Showing only the bar without a label
Without a label, users and assistive technology cannot tell what the progress refers to.
Building it with div and no role
The native progress element gives you the right semantics automatically.
Communicating progress only through color
Also provide the current value as text, such as a percentage or label.