Skip to content

Documentation

On this page

Progress

A completion bar is a <progress class="progress">. Omit value for the indeterminate stripe. A gauge is <meter class="meter">. No Progress plugin, no inner .progress-bar.

Sizes are minified and gzip. A plugin figure includes the Bootstrap runtime that plugin imports. Shipping every plugin is bootstrap.bundle.min.js at 23.3 KB gzip, not the sum of these rows.
What runs it JavaScript
Bootstrap 5.3 No Progress plugin. Markup is div.progress > .progress-bar with ARIA. Not in bootstrap.min.js
This repo progress and meter 0 KB
Markup this component accepts. The full inventory is /components.json.
Avoid
  • No inner .progress-bar and no style="width: …%". value and max are the fill.
  • Stacked bars are several values in one track. A <progress> has one value.

How it works

  • value and max replace style="width: …%" on an inner bar. The default max is 1.
  • The fill is currentcolor, so Bootstrap .text-* utilities recolor it. The track stays --bs-progress-bg.
  • .progress-bar-striped and .progress-bar-animated sit on the <progress>, not on a child.
  • No value means :indeterminate. That is Bootstrap’s animated stripe for an unknown duration. A circular busy state on a host is aria-busy on Spinner.
  • Height still comes from --bs-progress-height on .progress.

Labels

Associate a label with for/id, or wrap the control. The text inside the tags is only a fallback for old browsers.

70%
HTML
<label class="form-label" for="file">File progress</label>
<progress id="file" class="progress" value="70" max="100">70%</progress>

Values

value and max set the fill. There is no inner width style.

25% 50% 75% 100%
HTML
<label class="form-label" for="progress-25">25%</label>
<progress id="progress-25" class="progress mb-3" value="25" max="100">25%</progress>
<label class="form-label" for="progress-50">50%</label>
<progress id="progress-50" class="progress mb-3" value="50" max="100">50%</progress>
<label class="form-label" for="progress-75">75%</label>
<progress id="progress-75" class="progress mb-3" value="75" max="100">75%</progress>
<label class="form-label" for="progress-100">100%</label>
<progress id="progress-100" class="progress" value="100" max="100">100%</progress>

Height

Override --bs-progress-height. The native control uses that token for its box.

25% 25%
HTML
<label class="form-label" for="progress-thin">1px</label>
<progress id="progress-thin" class="progress mb-3" style="--bs-progress-height: 1px" value="25" max="100">25%</progress>
<label class="form-label" for="progress-tall">2rem</label>
<progress id="progress-tall" class="progress" style="--bs-progress-height: 2rem" value="25" max="100">25%</progress>

Backgrounds

The fill follows currentcolor. Use a text color utility, not .bg-* on a child bar.

25% 50% 75% 100%
HTML
<label class="form-label" for="progress-success">Success</label>
<progress id="progress-success" class="progress text-success mb-3" value="25" max="100">25%</progress>
<label class="form-label" for="progress-info">Info</label>
<progress id="progress-info" class="progress text-info mb-3" value="50" max="100">50%</progress>
<label class="form-label" for="progress-warning">Warning</label>
<progress id="progress-warning" class="progress text-warning mb-3" value="75" max="100">75%</progress>
<label class="form-label" for="progress-danger">Danger</label>
<progress id="progress-danger" class="progress text-danger" value="100" max="100">100%</progress>

Striped

Add .progress-bar-striped on the progress element.

40%
HTML
<label class="form-label" for="progress-striped">Striped</label>
<progress id="progress-striped" class="progress progress-bar-striped" value="40" max="100">40%</progress>

Animated stripes

Add .progress-bar-animated as well. prefers-reduced-motion turns the motion off.

75%
HTML
<label class="form-label" for="progress-animated">Animated stripe</label>
<progress id="progress-animated" class="progress progress-bar-striped progress-bar-animated" value="75" max="100">75%</progress>

Indeterminate

Leave value off. Assistive technology announces busy, not a percent.

Loading…
HTML
<label class="form-label" for="progress-busy">Loading</label>
<progress id="progress-busy" class="progress">Loading…</progress>

Accessibility

Label with <label for> or wrap the control. Text between the tags is a fallback for old browsers, not the accessible name.

Omit value only when the duration is unknown. Assistive technology then announces busy, not a percent. Do not add role="progressbar".

Browser support

Three columns, not one baseline. The same row is on the overview.
No script Polyfill No fallback
<progress> is Baseline Widely available (2015). <meter> is too (2017). The fill follows value / max with no script. None Without this CSS the native control still works. Token colors, radius, and the striped animation need appearance: none and the vendor bar pseudos.

Meter

<meter> is a gauge, not a task. It has min, max, low, high, and optimum. The browser colors the bar from those bounds: success when the value sits on the optimum side of the range, warning in the middle band, danger on the far side. Bootstrap has no meter component.

Fuel

low, high, and optimum tell the browser which band the value is in.

50/100
HTML
<label class="form-label" for="fuel">Fuel</label>
<meter id="fuel" class="meter" min="0" max="100" low="33" high="66" optimum="80" value="50">50/100</meter>

Bands

The same scale, three values. Green is nearest optimum, yellow is the middle band, red is the far side.

20/100 50/100 90/100
HTML
<label class="form-label" for="disk-low">Low (20, optimum is high)</label>
<meter id="disk-low" class="meter mb-3" min="0" max="100" low="33" high="66" optimum="80" value="20">20/100</meter>
<label class="form-label" for="disk-mid">Suboptimum (50)</label>
<meter id="disk-mid" class="meter mb-3" min="0" max="100" low="33" high="66" optimum="80" value="50">50/100</meter>
<label class="form-label" for="disk-high">Optimum (90)</label>
<meter id="disk-high" class="meter" min="0" max="100" low="33" high="66" optimum="80" value="90">90/100</meter>

Playground

Drag the range to change meter.value. This is a docs demo, not required markup.

50/100

low=33, high=66, optimum=80. Red below low, yellow in the middle band, green near optimum.