Linear progress indicator
A linear progress indicator shows how far a task has got, or that it is still running, along a horizontal bar. Give it a value and the bar fills to it; leave it looping when the wait has no known length. Below, flat and wavy bars fill and loop side by side, and a few switch on their own.
Reference docs
Choosing a loading indicator
Three kinds of indicator tell the reader to wait. Each suits a different job:
- Linear progress indicator: how far a task has got, or that it is still running, on a bar across the content, such as a file upload.
- Circular progress indicator: the same, in a compact ring, such as inside a button while it saves.
- Skeleton: the shape of content that is still loading, such as gray lines where a list will appear.
Two jobs belong elsewhere. A count or status on an icon is a badge, and a message once the work is done is a toast.
Choosing a variant
The mode decides what a reader sees, and the shape and thickness decide how it looks. Pick the mode first:
- Determinate: a task that reports how far it has got, such as a file upload. Set
andvalue .max - Indeterminate: a task with no known length, such as waiting for a server reply. Set
.indeterminate - Flat or wavy: a plain bar suits most waits; a bar with a moving wave suits products that use the Material 3 Expressive look. Set
@waveShape. - Standard or thick: a heavier track draws more attention to a wait. Set
.thickness
Built in
is clamped between 0 andvalue , so a value that overshoots cannot run past the end.max- A new
eases in over 250 milliseconds, andvalue turns the easing off for values that already move smoothly.immediate fades the indicator out instead of removing it.hide andwave-start limit the wave to the stretch of progress between them.wave-end andthickness@waveShapetake their defaults from the style configuration.
Using indicators well
- Report real progress when the task can: use a determinate indicator, and keep an indeterminate one for a wait of unknown length.
- Place the bar at the edge of what is loading, such as the top of a card or a page. For a compact spot, such as inside a button, use a Circular progress indicator instead.
- Show one indicator per wait, rather than several for one operation.
- Choose wavy or thick where the extra presence earns its space.
- When the shape of the arriving content is known, show a Skeleton in its place instead of a bar.
These rules follow Material 3 Expressive's guidance for progress indicators, on material.io.
Determinate
Set valuemaxvalue="65" with no maxmax="100" to count in percent, or pass a fraction.
Indeterminate
Set indeterminatevalue
Thickness
thicknessstandardthickstandard
Wave shape
@waveShape draws the bar flat (flatwavyflat
Wave region
On a wavy bar, wave-startwave-end
Immediate updates
A new valueimmediate
Hiding
hidehidden attribute takes it out of both.
In a card
A linear indicator along the top edge of a card shows that the card's content is on its way. Name the indicator for the task, and let the card's own text say the outcome.
Properties
| Property | Attribute | Type | Description |
|---|---|---|---|
hide | hide | booleandefault false | Fades the progress indicator out and stops an indeterminate loop. The element stays in the layout and in the accessibility tree. See Hiding. |
immediate | immediate | booleandefault false | Paints each new value at once, instead of easing to it over 250 ms. Set it when the value changes continuously, such as a scroll position: easing a value that is already smooth only makes the indicator trail the real one. See Immediate updates. |
indeterminate | indeterminate | booleandefault false | Shows progress with no known end, for an activity whose duration is unknown. See Indeterminate. |
max | max | numberdefault 1 | The value at which progress is complete. A value below 0.001 is treated as 0.001. See Determinate. |
thickness | thicknessstandard, thick | ProgressTrackThicknessProgressTrackThickness.Standard, .Thickdefault ProgressTrackThickness.Standard, from the style configuration | Sets how thick the indicator's line is. See Thickness. |
value | value | number | Progress to display, from 0 to max. Clamped to that range. See Determinate, Indeterminate, Immediate updates. |
waveEnd | wave-end | numberdefault 0.9 | The progress (0–1) at which the wave ends. Above it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
waveShape | wave-shapeflat, wavy | ProgressWaveShapeProgressWaveShape.Flat, .Wavydefault ProgressWaveShape.Flat, from the style configuration | Sets whether the indicator's line is flat or wavy. See Wave shape. |
waveStart | wave-start | numberdefault 0.1 | The progress (0–1) at which the wave begins. Below it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
Changing maxvaluevalue
Props
| Prop | Type | Description |
|---|---|---|
hide | booleandefault false | Fades the progress indicator out and stops an indeterminate loop. The element stays in the layout and in the accessibility tree. See Hiding. |
immediate | booleandefault false | Paints each new value at once, instead of easing to it over 250 ms. Set it when the value changes continuously, such as a scroll position: easing a value that is already smooth only makes the indicator trail the real one. See Immediate updates. |
indeterminate | booleandefault false | Shows progress with no known end, for an activity whose duration is unknown. See Indeterminate. |
max | numberdefault 1 | The value at which progress is complete. A value below 0.001 is treated as 0.001. See Determinate. |
thickness | ProgressTrackThicknessTypeProgressTrackThickness.Standard, .Thickdefault ProgressTrackThickness.Standard, from the style configuration | Sets how thick the indicator's line is. See Thickness. |
value | number | Progress to display, from 0 to max. Clamped to that range. See Determinate, Indeterminate, Immediate updates. |
waveEnd | numberdefault 0.9 | The progress (0–1) at which the wave ends. Above it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
waveShape | ProgressWaveShapeTypeProgressWaveShape.Flat, .Wavydefault ProgressWaveShape.Flat, from the style configuration | Sets whether the indicator's line is flat or wavy. See Wave shape. |
waveStart | numberdefault 0.1 | The progress (0–1) at which the wave begins. Below it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
Changing maxvaluevalue
Parameters
| Parameter | Type | Description |
|---|---|---|
Hide | bool?default false | Fades the progress indicator out and stops an indeterminate loop. The element stays in the layout and in the accessibility tree. See Hiding. |
Immediate | bool?default false | Paints each new value at once, instead of easing to it over 250 ms. Set it when the value changes continuously, such as a scroll position: easing a value that is already smooth only makes the indicator trail the real one. See Immediate updates. |
Indeterminate | bool?default false | Shows progress with no known end, for an activity whose duration is unknown. See Indeterminate. |
Max | double?default 1 | The value at which progress is complete. A value below 0.001 is treated as 0.001. See Determinate. |
Thickness | ProgressTrackThickness?ProgressTrackThickness.Standard, .Thickdefault ProgressTrackThickness.Standard, from the style configuration | Sets how thick the indicator's line is. See Thickness. |
Value | double? | Progress to display, from 0 to Max. Clamped to that range. See Determinate, Indeterminate, Immediate updates. |
WaveEnd | double?default 0.9 | The progress (0–1) at which the wave ends. Above it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
WaveShape | ProgressWaveShape?ProgressWaveShape.Flat, .Wavydefault ProgressWaveShape.Flat, from the style configuration | Sets whether the indicator's line is flat or wavy. See Wave shape. |
WaveStart | double?default 0.1 | The progress (0–1) at which the wave begins. Below it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
Changing maxvaluevalue
Inputs
| Input | Type | Description |
|---|---|---|
hide | booleandefault false | Fades the progress indicator out and stops an indeterminate loop. The element stays in the layout and in the accessibility tree. See Hiding. |
immediate | booleandefault false | Paints each new value at once, instead of easing to it over 250 ms. Set it when the value changes continuously, such as a scroll position: easing a value that is already smooth only makes the indicator trail the real one. See Immediate updates. |
indeterminate | booleandefault false | Shows progress with no known end, for an activity whose duration is unknown. See Indeterminate. |
max | numberdefault 1 | The value at which progress is complete. A value below 0.001 is treated as 0.001. See Determinate. |
thickness | ProgressTrackThicknessTypeProgressTrackThickness.Standard, .Thickdefault ProgressTrackThickness.Standard, from the style configuration | Sets how thick the indicator's line is. See Thickness. |
value | number | Progress to display, from 0 to max. Clamped to that range. See Determinate, Indeterminate, Immediate updates. |
waveEnd | numberdefault 0.9 | The progress (0–1) at which the wave ends. Above it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
waveShape | ProgressWaveShapeTypeProgressWaveShape.Flat, .Wavydefault ProgressWaveShape.Flat, from the style configuration | Sets whether the indicator's line is flat or wavy. See Wave shape. |
waveStart | numberdefault 0.1 | The progress (0–1) at which the wave begins. Below it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
Changing maxvaluevalue
Props
| Prop | Type | Description |
|---|---|---|
hide | booleandefault false | Fades the progress indicator out and stops an indeterminate loop. The element stays in the layout and in the accessibility tree. See Hiding. |
immediate | booleandefault false | Paints each new value at once, instead of easing to it over 250 ms. Set it when the value changes continuously, such as a scroll position: easing a value that is already smooth only makes the indicator trail the real one. See Immediate updates. |
indeterminate | booleandefault false | Shows progress with no known end, for an activity whose duration is unknown. See Indeterminate. |
max | numberdefault 1 | The value at which progress is complete. A value below 0.001 is treated as 0.001. See Determinate. |
thickness | ProgressTrackThicknessTypeProgressTrackThickness.Standard, .Thickdefault ProgressTrackThickness.Standard, from the style configuration | Sets how thick the indicator's line is. See Thickness. |
value | number | Progress to display, from 0 to max. Clamped to that range. See Determinate, Indeterminate, Immediate updates. |
waveEnd | numberdefault 0.9 | The progress (0–1) at which the wave ends. Above it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
waveShape | ProgressWaveShapeTypeProgressWaveShape.Flat, .Wavydefault ProgressWaveShape.Flat, from the style configuration | Sets whether the indicator's line is flat or wavy. See Wave shape. |
waveStart | numberdefault 0.1 | The progress (0–1) at which the wave begins. Below it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
Changing maxvaluevalue
Props
| Prop | Type | Description |
|---|---|---|
hide | booleandefault false | Fades the progress indicator out and stops an indeterminate loop. The element stays in the layout and in the accessibility tree. See Hiding. |
immediate | booleandefault false | Paints each new value at once, instead of easing to it over 250 ms. Set it when the value changes continuously, such as a scroll position: easing a value that is already smooth only makes the indicator trail the real one. See Immediate updates. |
indeterminate | booleandefault false | Shows progress with no known end, for an activity whose duration is unknown. See Indeterminate. |
max | numberdefault 1 | The value at which progress is complete. A value below 0.001 is treated as 0.001. See Determinate. |
thickness | ProgressTrackThicknessTypeProgressTrackThickness.Standard, .Thickdefault ProgressTrackThickness.Standard, from the style configuration | Sets how thick the indicator's line is. See Thickness. |
value | number | Progress to display, from 0 to max. Clamped to that range. See Determinate, Indeterminate, Immediate updates. |
waveEnd | numberdefault 0.9 | The progress (0–1) at which the wave ends. Above it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
waveShape | ProgressWaveShapeTypeProgressWaveShape.Flat, .Wavydefault ProgressWaveShape.Flat, from the style configuration | Sets whether the indicator's line is flat or wavy. See Wave shape. |
waveStart | numberdefault 0.1 | The progress (0–1) at which the wave begins. Below it the wave is flat. Applies only to a determinate wavy indicator. See Wave region. |
Changing maxvaluevalue
Each attribute value has its own tokens; a cell shows its token's value, and selecting the cell shows the token's fallback path, with each name and value ready to copy. For example, the standard column's track-thickness row is --ct-linear-progress-standard-track-thickness, which defaults to 4px.
Thickness
| Name | standard | thick |
|---|---|---|
track-thickness | 4px --ct-linear-progress-standard-track-thickness | 8px --ct-linear-progress-thick-track-thickness |
Other tokens
These stay the same whatever the thickness.
| Token | Value |
|---|---|
--ct-linear-progress-active-indicator-color | --ct-sys-color-primary --ct-linear-progress-active-indicator-color |
--ct-linear-progress-stop-indicator-size | 4px --ct-linear-progress-stop-indicator-size |
--ct-linear-progress-track-color | --ct-sys-color-secondary-container --ct-linear-progress-track-color |
--ct-linear-progress-track-indicator-space | 4px --ct-linear-progress-track-indicator-space |
--ct-linear-progress-wave-amplitude | 3px --ct-linear-progress-wave-amplitude |
--ct-linear-progress-wave-wavelength | 40px --ct-linear-progress-wave-wavelength |
Names and states
A linear progress indicator is exposed to assistive technology as a progress bar and follows the WAI-ARIA Authoring Practices guidance on meters, gauges, and progress indicators.
- A screen reader announces a range from 0 to
and the currentmax . An indeterminate indicator announces no current value.value - The announced value is the clamped
invalue units, not a percentage.max - The indicator has no default name. Give every one an
aria-labelthat says what is progressing. - Only
aria-labelnames the indicator.aria-labelledby,aria-describedby, andaria-valuetexthave no effect. - A hidden indicator is still a progress bar for assistive technology unless it is removed from the page or marked
hidden; see Hiding. - The indicator is a progress bar, not a live region, and the indicator fires no events. Announce completion yourself, in a live region of your own.
- A compact spot suits a Circular progress indicator, which names itself the same way. Content that has not arrived yet suits a Skeleton, which has a default name.
Keyboard and focus
| Key | Action |
|---|---|
| None | The indicator takes no keyboard input. |
- The indicator is not focusable and shows no focus ring.
- To let a keyboard user act on a wait, such as canceling an upload, give the page a button for it.
Pointer and touch
- The indicator takes no pointer input, so a click passes through to whatever sits beneath it.
- It has no touch target, so WCAG 2.5.8 Target Size (Minimum) has nothing to measure.
Display settings
- Under forced colors, the indicator takes a 1 pixel outline in the system text color.
- With reduced motion requested, a wavy bar's wave holds still, and the easing of a new
completes at once.value
Standards
With its defaults, a linear progress indicator meets zero WCAG 2.2 success criteria on its own, because it takes no focus. Three depend on how you use it:
- 2.2.2 Pause, Stop, Hide (A): an indeterminate loop that runs for more than five seconds needs a way to stop, so set
when the wait ends or offer a control that cancels it.hide - 4.1.2 Name, Role, Value (A): the role and values are built in, so set an
aria-labelfor the name. - 4.1.3 Status Messages (AA): announce completion in a live region of your own, since the indicator fires no event.