Determinate — flat
value in 0–100 drives the active fill. Stop indicator (4dp dot at the trailing edge) renders by default in determinate mode.
Track height stays at 4dp regardless of active thickness; the active indicator scales with thickness.
4dp (default) — value 0 / 25 / 50 / 75 / 100
8dp (sample) — stop indicator squashed to 4×2dp
Determinate — wavy
Active indicator is a sine wave (3dp amplitude / 40dp wavelength). The phase animates so the wave appears to flow along the progress.
Total component height is thickness + 2 × amplitude = 10dp (4dp wavy) / 14dp (8dp wavy).
Indeterminate
Omit value for indeterminate. Two small bars traverse the track left→right, offset by half a 2s cycle so one is always crossing.
No stop indicator (per spec).
Flat 4dp / 8dp
Wavy 4dp / 8dp
Stop indicator modes
stop-indicator = auto (default — determinate only) / always / never.
Per accessibility spec, the dot is required when track contrast with the surrounding container is below 3:1.
auto (default, determinate → on)
never
always (visible even on indeterminate — non-spec but supported)
RTL
Drawing math is always LTR; the whole indicator mirrors via :host(:dir(rtl)) so the active fill and indeterminate sweep
move in the correct reading direction under dir="rtl".
Determinate 60% — fill grows from the right
Indeterminate — bars sweep right to left
Live demo — determinate slider
Drag the slider to drive value. Wavy mode keeps phase animation running while the fill snaps to your input.
In a card
Linear indicators sit on the leading edge of a loading container.
Card title
The progress bar above marks the loading edge of this container.
Reduced motion + paused
prefers-reduced-motion: reduce (DevTools ▸ Rendering) freezes the animations.
paused attribute halts the rAF loop on demand — useful for visual-regression tests.
Sample usage
<!-- Determinate, flat (default) -->
<material-linear-progress value="60" label="Saving…"></material-linear-progress>
<!-- Determinate, wavy, thicker -->
<material-linear-progress value="60" wavy thickness="8" label="Saving…"></material-linear-progress>
<!-- Indeterminate (omit value) -->
<material-linear-progress label="Loading"></material-linear-progress>
<!-- Stop indicator: auto (default) | always | never -->
<material-linear-progress value="80" stop-indicator="never"></material-linear-progress>
<!-- Pause both spin + wave (e.g., snapshot tests) -->
<material-linear-progress wavy paused></material-linear-progress>