Progress Bar
A linear indicator that shows how far a process has advanced toward completion.
Plain English
A progress bar works because it makes time feel manageable. Watching 45% climb to 100% during a file upload reduces anxiety compared to an endless spinner. There are two types: determinate (you know the percentage — use it) and indeterminate (you only know work is happening — show an animated slide). For multi-step flows like onboarding or checkout, a stepped progress bar shows which stage the user is on.
Technical
Determinate: inner div with width controlled by state (transition: width 200ms ease). Indeterminate: overflow-hidden parent with inner div at 30% width with @keyframes slide { 0% { transform: translateX(-100%) } 100% { transform: translateX(400%) } } animation: slide 1.5s ease-in-out infinite. Height typically 4–8px. ARIA: role="progressbar" aria-valuenow aria-valuemin aria-valuemax on the track element.
Live Demo
Determinate
0%Indeterminate
Stepped
Step 1 of 4Use determinate when you have a value — only use indeterminate when the end is truly unknown.
Usage
✓ Good usage
A file upload showing "Uploading… 67%" with a blue bar filling left to right — users can predict when it will finish.
✗ Bad usage
An indeterminate progress bar shown during a 0.3s search — users barely see it, and it implies a longer wait than there is.
Recommended values
- Height: 4px (subtle), 8px (prominent)
- Color: brand primary for fill, light neutral for track
- Indeterminate speed: 1.5s ease-in-out infinite
- Stepped: 4–6 steps maximum
- Show percentage label for determinate bars over 5s
- ARIA: role="progressbar" aria-valuenow aria-valuemin aria-valuemax
Common mistakes
- Using indeterminate when you have percentage data — always use determinate when the value is known.
- Missing ARIA attributes — screen readers cannot announce progress without aria-valuenow.
- Jumping from 0% to 100% instantly — the bar should animate smoothly even for fast operations.
AI Prompt Example
Copy this into Claude, Cursor, Bolt, or v0.
Add a progress bar to the file upload component. Show a determinate bar (0–100%) updating every time a chunk uploads. Use height 6px, brand color fill, animate width transitions. Add role="progressbar" aria-valuenow aria-valuemin="0" aria-valuemax="100". Show the percentage as text beside the bar.