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

ClassHeightBorder radius
default0.75em0.325rem
is-medium1.5rem0.725rem
is-large2.5rem1rem

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>
10%
80%

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 valueUse case
defaultvar(--primary)General purpose
is-successvar(--success)Completion, passed states
is-dangervar(--danger)Errors, critical thresholds
is-warningvar(--warning)Caution, near-limit states
is-infovar(--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>
Complete

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.

VariableDefaultDescription
--progress-trackvar(--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 — .progress is a visual-only component and carries no implicit ARIA semantics.
  • Add role="progressbar", aria-valuenow, aria-valuemin, and aria-valuemax to .progress-bar for screen reader support.
  • Always provide a visible or accessible label describing what the bar represents.
  • For indeterminate states, omit aria-valuenow and set aria-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>

FrontAlign