Progress

A horizontal fill bar used to show progress for determinate and indeterminate states

Examples

Bar -- basic usage

<div
            class="progress"
            role="progressbar"
            aria-valuenow="60"
            aria-valuemin="0"
            aria-valuemax="100"
            aria-label="Upload"
        >
            <div class="progress-bar" style="inline-size: 60%"></div>
        </div>

With inline label

60%
35%
<div class="stack">
            <div
                class="progress is-lg"
                role="progressbar"
                aria-valuenow="60"
                aria-valuemin="0"
                aria-valuemax="100"
                style="
                    --progress-fill: var(--color-primary);
                    --progress-label-color: var(--color-on-primary);
                "
            >
                <div class="progress-bar" style="inline-size: 60%">60%</div>
            </div>
            <div
                class="progress is-lg"
                role="progressbar"
                aria-valuenow="35"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <div class="progress-bar" style="inline-size: 35%">35%</div>
            </div>
        </div>

Sizes

<div class="stack">
            <div
                class="progress is-sm"
                role="progressbar"
                aria-valuenow="40"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <div class="progress-bar" style="inline-size: 40%"></div>
            </div>
            <div
                class="progress"
                role="progressbar"
                aria-valuenow="55"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <div class="progress-bar" style="inline-size: 55%"></div>
            </div>
            <div
                class="progress is-lg"
                role="progressbar"
                aria-valuenow="70"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <div class="progress-bar" style="inline-size: 70%"></div>
            </div>
        </div>

Status colors

80%
65%
90%
<div class="stack">
            <div
                class="progress is-lg"
                role="progressbar"
                aria-valuenow="80"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <div class="progress-bar is-success" style="inline-size: 80%">80%</div>
            </div>
            <div
                class="progress is-lg"
                role="progressbar"
                aria-valuenow="65"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <div class="progress-bar is-warning" style="inline-size: 65%">65%</div>
            </div>
            <div
                class="progress is-lg"
                role="progressbar"
                aria-valuenow="90"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <div class="progress-bar is-danger" style="inline-size: 90%">90%</div>
            </div>
        </div>

Indeterminate

<div
            class="progress is-indeterminate"
            role="progressbar"
            aria-label="Loading"
            aria-valuetext="Loading"
        >
            <div class="progress-bar"></div>
        </div>

Stacked segments

<div
            class="progress is-lg is-stacked"
            role="progressbar"
            aria-valuenow="79"
            aria-valuemin="0"
            aria-valuemax="100"
            aria-label="Storage usage"
        >
            <div class="progress-bar is-success" style="inline-size: 50%"></div>
            <div class="progress-bar is-warning" style="inline-size: 22%"></div>
            <div class="progress-bar is-danger" style="inline-size: 7%"></div>
        </div>

Ring -- basic usage

25%
50%
75%
100%
<div class="cluster">
            <div
                class="progress-ring"
                style="--progress-value: 25"
                role="progressbar"
                aria-valuenow="25"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>25%</span>
            </div>
            <div
                class="progress-ring"
                style="--progress-value: 50"
                role="progressbar"
                aria-valuenow="50"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>50%</span>
            </div>
            <div
                class="progress-ring"
                style="--progress-value: 75"
                role="progressbar"
                aria-valuenow="75"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>75%</span>
            </div>
            <div
                class="progress-ring"
                style="--progress-value: 100"
                role="progressbar"
                aria-valuenow="100"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>100%</span>
            </div>
        </div>

Ring sizes

60%
60%
60%
<div class="cluster">
            <div
                class="progress-ring is-sm"
                style="--progress-value: 60"
                role="progressbar"
                aria-valuenow="60"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>60%</span>
            </div>
            <div
                class="progress-ring"
                style="--progress-value: 60"
                role="progressbar"
                aria-valuenow="60"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>60%</span>
            </div>
            <div
                class="progress-ring is-lg"
                style="--progress-value: 60"
                role="progressbar"
                aria-valuenow="60"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>60%</span>
            </div>
        </div>

Ring status colors

80%
65%
90%
<div class="cluster">
            <div
                class="progress-ring is-success"
                style="--progress-value: 80"
                role="progressbar"
                aria-valuenow="80"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>80%</span>
            </div>
            <div
                class="progress-ring is-warning"
                style="--progress-value: 65"
                role="progressbar"
                aria-valuenow="65"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>65%</span>
            </div>
            <div
                class="progress-ring is-danger"
                style="--progress-value: 90"
                role="progressbar"
                aria-valuenow="90"
                aria-valuemin="0"
                aria-valuemax="100"
            >
                <span>90%</span>
            </div>
        </div>

Ring inside a card

67%

Storage used

89%

API quota

<div class="grid" style="--grid-min: 12rem">
            <div
                class="card stack is-center text-center"
                style="
                    --avatar-status-ring-color: var(--color-surface-raised);
                    --progress-ring-cutout-bg: var(--color-surface-raised);
                "
            >
                <div
                    class="progress-ring is-success"
                    style="--progress-value: 67"
                    role="progressbar"
                    aria-valuenow="67"
                    aria-valuemin="0"
                    aria-valuemax="100"
                >
                    <span>67%</span>
                </div>
                <p class="text-muted">Storage used</p>
            </div>
            <div
                class="card stack is-center text-center"
                style="--progress-ring-cutout-bg: var(--color-surface-raised)"
            >
                <div
                    class="progress-ring is-warning"
                    style="--progress-value: 89"
                    role="progressbar"
                    aria-valuenow="89"
                    aria-valuemin="0"
                    aria-valuemax="100"
                >
                    <span>89%</span>
                </div>
                <p class="text-muted">API quota</p>
            </div>
        </div>

Dashboard composition

Storage 67%
67 GB of 100 GB
API quota 89%
89k of 100k requests
Build minutes 34%
340 of 1,000 minutes
<div class="grid" style="--grid-min: 14rem">
            <div class="card stack">
                <div class="stat is-compact">
                    <span class="stat-label">Storage</span>
                    <span class="stat-value">67%</span>
                </div>
                <div
                    class="progress is-sm"
                    role="progressbar"
                    aria-valuenow="67"
                    aria-valuemin="0"
                    aria-valuemax="100"
                >
                    <div class="progress-bar" style="inline-size: 67%"></div>
                </div>
                <span class="text-muted">67 GB of 100 GB</span>
            </div>
            <div class="card stack">
                <div class="stat is-compact">
                    <span class="stat-label">API quota</span>
                    <span class="stat-value">89%</span>
                </div>
                <div
                    class="progress is-sm"
                    role="progressbar"
                    aria-valuenow="89"
                    aria-valuemin="0"
                    aria-valuemax="100"
                >
                    <div class="progress-bar is-warning" style="inline-size: 89%"></div>
                </div>
                <span class="text-muted">89k of 100k requests</span>
            </div>
            <div class="card stack">
                <div class="stat is-compact">
                    <span class="stat-label">Build minutes</span>
                    <span class="stat-value">34%</span>
                </div>
                <div
                    class="progress is-sm"
                    role="progressbar"
                    aria-valuenow="34"
                    aria-valuemin="0"
                    aria-valuemax="100"
                >
                    <div class="progress-bar is-success" style="inline-size: 34%"></div>
                </div>
                <span class="text-muted">340 of 1,000 minutes</span>
            </div>
        </div>

Source comments

Progress -- horizontal fill bar and circular ring for
determinate (and, for the bar, indeterminate) progress
states (extra).

Two related components in one file because they share token
names and serve the same semantic purpose -- visual
representation of a fraction-of-complete value.

Markup (bar):
  <div class="progress" role="progressbar"
       aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"
       aria-label="Upload">
      <div class="progress-bar" style="inline-size: 60%"></div>
  </div>

  <!-- With inline label -->
  <div class="progress" role="progressbar" ...>
      <div class="progress-bar" style="inline-size: 60%">60%</div>
  </div>

  <!-- Indeterminate (no value yet) -->
  <div class="progress is-indeterminate" role="progressbar"
       aria-label="Loading" aria-valuetext="Loading">
      <div class="progress-bar"></div>
  </div>

  <!-- Stacked segments -->
  <div class="progress is-stacked" role="progressbar" ...>
      <div class="progress-bar is-success" style="inline-size: 60%"></div>
      <div class="progress-bar is-warning" style="inline-size: 30%"></div>
  </div>

Markup (ring):
  <div class="progress-ring" style="--progress-value: 75"
       role="progressbar" aria-valuenow="75"
       aria-valuemin="0" aria-valuemax="100">
      <span>75%</span>
  </div>

The ring uses a conic-gradient for the fill arc and a centered
::after pseudo-element to punch the inner cutout. The cutout's
background follows --progress-ring-cutout-bg (defaults to
--color-surface) so consumers inside cards or other elevated
surfaces can override it (`--progress-ring-cutout-bg:
var(--color-surface-raised)` on the card or the ring).

No .is-indeterminate on the ring -- circular indeterminate
loading is what the existing .spinner component is for.

Archetype: Slotted container (P3) for the bar, Atom (P3) for
the ring. Both are pure CSS, no JS.

Default fills use the soft chromatic scale
(--color-{family}-soft) -- tuned for compositional elegance, not
state-alarm volume. Inline labels on .progress-bar inherit
--color-text by default, which has decent contrast on soft
fills in light mode and marginal contrast in dark. Consumers
needing labels-with-guaranteed-contrast should override back
to the loud chromatic token:

  <div class="progress" style="--progress-fill: var(--color-primary);
                               --progress-label-color: var(--color-on-primary);">
      <div class="progress-bar" style="inline-size: 60%">60%</div>
  </div>

The default soft scale matches the rule of thumb: state
communication stays loud (alerts, validation, badges); data
display goes soft (progress, charts, multi-color
visualizations).

Reference

Source: src/css/extras/progress.css

Applies to

.progress

Classes

ClassKindDescription
.is-smvariantSmaller thickness for the progress bar
.is-lgvariantLarger thickness for the progress bar
.progress-bar.is-successvariantSuccess color variant for the internal progress-bar
.progress-bar.is-warningvariantWarning color variant for the internal progress-bar
.progress-bar.is-dangervariantDanger color variant for the internal progress-bar
.is-stackedvariantStacked segments, bars flush edge-to-edge inside one track. The first / last segments keep the track's outer radius; middle segments are square so the seams meet flat.
.is-indeterminatevariantAn indeterminate bar slides across the track on a loop. Container becomes positioning context; the .progress-bar inside is absolutely positioned so the keyframe animates its own position and size without shifting the surrounding layout.

Slots

SlotDescription
.progress-barFilled portion of the bar

Tokens

TokenDefaultDescription
--progress-height0.5remTrack height of the progress bar
--progress-radiusvar(--radius-pill)Corner radius for the bar track and fill
--progress-bgvar(--color-fill)Background color of the unfilled track
--progress-fillvar(--color-primary-soft)Fill color for the completed portion
--progress-label-colorvar(--color-text)Text color for inline percentage labels
--progress-transitionvar(--transition-normal)Transition for animated width changes on the fill

Related: Progress Ring

A circular progress ring for showing determinate states

Source: src/css/extras/progress.css

Applies to

.progress-ring

Classes

ClassKindDescription
.is-successvariantSuccess color variant for the ring fill
.is-warningvariantWarning color variant for the ring fill
.is-dangervariantDanger color variant for the ring fill
.is-smvariantSmall ring variant (3rem diameter)
.is-lgvariantLarge ring variant (8rem diameter)

Tokens

TokenDefaultDescription
--progress-ring-size5remOuter diameter of the ring
--progress-ring-width0.375remThickness of the ring stroke
--progress-fillvar(--color-primary-soft)Fill color for the ring arc
--progress-bgvar(--color-fill)Background color for the unfilled portion of the ring
--progress-ring-cutout-bgvar(--color-surface)Background color of the inner cutout
--progress-value0Consumer-set progress value, 0 to 100