Fylgja Progress
<progress> shows how far a task has run, such as an upload or an import. It
only moves forward, and it can run without a value at all when the duration is
unknown. Fylgja Form Extend restyles it so the track and fill look the same
across browsers.
Preview
<label>
Uploading
<progress max="100" value="64">64%</progress>
</label>
<label>
Processing
<progress></progress>
</label>Usage
- Give the bar
maxandvaluefor a known amount of work. - Leave
valueoff entirely for an indeterminate bar, which animates rather than filling to a point. - Put the text inside the element as a fallback, for example
64%. Browsers that render the bar ignore it. - Recolor the fill with
--fill, and size the track with--track-heightand--track-color.
Anatomy
<label>wraps the bar and its text, so noforis needed.maxandvalueset how much of the task is done. Novaluemeans unknown.--fillis the filled portion, defaulting to--brand. There are no states here, unlike Meter.
Variants
Set --fill on the <progress> itself, not on the wrapping label, since Form
Extend declares it on the element and an inherited value loses to that.
<label>
Uploading
<progress max="100" value="64" style="--fill: oklch(58% 0.21 var(--hue-teal))">64%</progress>
</label>Accessibility
- The element carries its role and value natively, so a screen reader announces the progress without any ARIA.
- Keep the label. A bare bar tells a screen reader user a percentage but not what it measures.
- An indeterminate bar animates. Readers who prefer reduced motion get a calmer version from Fylgja.
FAQ
How do I show a task with no known duration?
Leave the value off. Without it the bar renders as indeterminate and animates instead of filling to a point, which is the second example above.
When do I use a progress bar instead of a meter?
A progress bar shows how far a task has run and only moves forward. Use Meter for a measurement in a known range, such as disk usage, where the value can go up or down.
Why is the fill the brand color?
--fill defaults to --brand, so a progress bar matches your theme with no setup. Set --fill on the element to change it.