Progress Bar
A Progress Bar communicates how much of a task has been completed. It is a pure CSS component with no JavaScript required for rendering — only for updating values.
Use Progress Bar for:
- File upload and download tracking
- Multi-step form completion
- Installation and build progress
- Storage usage indicators
- Stacked segment breakdowns
Getting Started
The Progress Bar consists of a .progress container and one or more .progress-bar fill elements inside it. The fill width is controlled via a w-* utility class on .progress-bar.
The .progress-bar transitions its width smoothly over 0.5s ease, so incrementing the width from JavaScript produces a fluid animation automatically.
HTML Structure
<div class="progress">
<div class="progress-bar w-3fr5">60%</div>
</div>
Progress Size
| Class | Height | Border radius |
|---|---|---|
| default | 0.75em | 0.325rem |
is-medium | 1.5rem | 0.725rem |
is-large | 2.5rem | 1rem |
Label text inside .progress-bar is only legible when the bar is tall enough. For the default thin size, omit the label or render it outside the bar.
<div class="progress">
<div class="progress-bar w-1fr12"></div>
</div>
<div class="progress is-medium">
<div class="progress-bar w-1fr6">10%</div>
</div>
<div class="progress is-large">
<div class="progress-bar w-3fr4">80%</div>
</div>
Color Themes
Apply a color theme by adding a modifier class to the .progress wrapper. Each theme sets --progress-track to the corresponding color token — the fill color and the 14% opacity track tint both update from this single variable.
| Class | --progress-track value | Use case |
|---|---|---|
| default | var(--primary) | General purpose |
is-success | var(--success) | Completion, passed states |
is-danger | var(--danger) | Errors, critical thresholds |
is-warning | var(--warning) | Caution, near-limit states |
is-info | var(--info) | Informational, neutral progress |
.progress.is-success {
--progress-track: var(--success);
}
.progress {
background-color: color-mix(in oklch, var(--progress-track, var(--primary)) 14%, transparent);
}
<div className="progress is-medium">
<div className="progress-bar w-3fr4"></div>
</div>
<div className="progress is-medium is-success">
<div className="progress-bar w-full">Complete</div>
</div>
<div className="progress mb-2 is-medium is-danger">
<div className="progress-bar w-3fr4"></div>
</div>
<div className="progress is-medium is-warning">
<div className="progress-bar w-3fr4"></div>
</div>
<div className="progress is-medium is-info">
<div className="progress-bar w-3fr4"></div>
</div>
Striped Progress Bar
Add is-striped to .progress-bar to overlay a diagonal stripe pattern on the fill. The stripe is an absolutely positioned semi-transparent white gradient layer rendered above the fill color.
<div class="progress">
<div class="progress-bar is-striped w-1fr2"></div>
</div>
Animated Stripes
Add is-animated to the .progress container to make the stripe pattern march continuously — ideal for active upload or processing states.
is-animated only has a visible effect when is-striped is also present on .progress-bar. Without stripes there is no pattern to animate.
<div class="progress is-medium is-animated">
<div class="progress-bar is-striped w-3fr4"></div>
</div>
Indeterminate Progress
For an unknown completion time, use is-animated and is-striped on a bar set to width: 100%. The marching stripes signal ongoing activity without implying a percentage.
<div class="progress is-medium is-animated">
<div class="progress-bar is-striped w-full"></div>
</div>
JavaScript Progress Updates
Because .progress-bar transitions its width smoothly by default, updating the inline style from JavaScript produces a fluid animation with no extra code.
const bar = document.querySelector('.progress-bar');
let progress = 0;
const interval = setInterval(() => {
progress += 10;
bar.style.width = progress + '%';
bar.textContent = progress + '%';
if (progress >= 100) {
clearInterval(interval);
bar.textContent = 'Complete!';
}
}, 500);
CSS Custom Properties
The progress color system is driven by a single --progress-track variable. Override it inline to create a one-off color without a theme class.
| Variable | Default | Description |
|---|---|---|
--progress-track | var(--primary) | Fill color for .progress-bar and the tinted track background. |
<!-- Custom teal progress -->
<div class="progress is-medium" style="--progress-track: var(--teal-500)">
<div class="progress-bar w-2fr3"></div>
</div>
<!-- Custom purple progress -->
<div class="progress is-large" style="--progress-track: #7c3aed">
<div class="progress-bar w-2fr3"></div>
</div>
The track background is automatically derived from the same token at 14% opacity — both the fill and the empty track update together from a single override.
Accessibility
Recommended practices:
- Use the native
<progress>element when full accessibility support is required —.progressis a visual-only component and carries no implicit ARIA semantics. - Add
role="progressbar",aria-valuenow,aria-valuemin, andaria-valuemaxto.progress-barfor screen reader support. - Always provide a visible or accessible label describing what the bar represents.
- For indeterminate states, omit
aria-valuenowand setaria-label="Loading"on the bar.
<!-- Accessible determinate progress -->
<div class="progress is-medium">
<div class="progress-bar w-2fr3"
role="progressbar"
aria-valuenow="65"
aria-valuemin="0"
aria-valuemax="100"
aria-label="Upload progress">
65%
</div>
</div>
<!-- Accessible indeterminate progress -->
<div class="progress is-medium is-animated">
<div class="progress-bar is-striped w-full"
role="progressbar"
aria-label="Loading">
</div>
</div>