<progress> Progress bar

Shows how far along a task is, like a file download.

<progress> shows how complete a task is. Set value and max, which defaults to 1. With no value it turns into an indeterminate bar: something is happening, amount unknown.

It is meant for progress over time, such as an upload or a multi-step form. A measurement inside a known range, like disk usage or a score, belongs in <meter>. Add a label so the bar has a name.

The value and max attributes and the indeterminate state are explained in the progress element in the HTML Living Standard (opens in a new tab). Compare it with the meter element.

Syntax

<label for="id">Task</label>
<progress id="id" value="30" max="100">30%</progress>

When to use it

File uploads, installs, videos being processed and the steps of a multi-page form all move toward being finished, and <progress> shows how far they have got. Leave out the value and you get a busy indicator, for when work is happening but you cannot say how much is left.

Some values are levels, not progress: storage used, a quiz score, a fuel gauge. Those are a meter. And sometimes a number is all people need. "40 of 120 photos uploaded" says more than a bar, and it sits nicely next to one.

Styling is awkward because the browser draws the bar. First reset it with appearance:none, then color it through browser-specific pseudo-elements like ::-webkit-progress-value and ::-moz-progress-bar. Give each its own rule. Group them in one selector list and any browser that does not know one of them throws the whole rule away. Never show a fake bar with no real progress behind it.

Attributes

AttributeWhat it does
valueAmount completed.
maxTotal amount of work (default 1).

Live example

Edit the code and watch the preview.

<label for="up">Upload</label>
<progress id="up" value="70" max="100">70%</progress>
<p>Loading: <progress>Please wait</progress></p>

More examples

Step indicator in a form

In a four-step sign-up, value="2" and max="4" show the user's position. The step is written out in text as well. A bar by itself does not say how many steps are left.

<form>
  <label for="steps">Step 2 of 4: Your address</label>
  <progress id="steps" value="2" max="4">Step 2 of 4</progress>
  <p>
    <label for="city">City</label>
    <input id="city" name="city" autocomplete="address-level2">
  </p>
  <button>Next step</button>
</form>

Custom colors with separate rules

Once appearance:none is set, browser-specific pseudo-elements style the track and the filled part. Every one gets a separate rule. A browser that does not recognise a selector skips that rule and still applies the rest.

<style>
progress{appearance:none;width:14em;height:1em;border:0;background:#eee}
progress::-webkit-progress-bar{background:#eee}
progress::-webkit-progress-value{background:#2a7}
progress::-moz-progress-bar{background:#2a7}
</style>
<label for="up">Uploading photos: 65%</label>
<progress id="up" value="65" max="100">65%</progress>

Tip: Tasks get progress. Measurements get meter.

Browser support

progress works in all current browsers and is part of the HTML Living Standard (see progress element support (opens in a new tab)). It looks like the operating system by default, and each browser animates the indeterminate state its own way. Only browsers without support show the text inside the element. That text is your fallback.

Accessibility

Label the progress bar and put the percentage in its text content, so the value is still there when the bar cannot be drawn. Why the bar needs a name is explained in the W3C note Understanding Name, Role, Value (opens in a new tab).

Common mistakes

Wrong

<progress value="70"></progress>

Right

<label for="up">Upload</label>
<progress id="up" value="70" max="100">70%</progress>

With no max, value has to fall between 0 and 1. A label gives the bar its name.

Frequently asked questions

What is the difference between progress and meter?

They measure different things. <progress> tracks how far a task has got toward completion, such as a file upload or a multi-step form. <meter> shows a scalar value in a known range, like disk usage, a test score or battery level, and can have low, high and optimum thresholds. Keep each to its own job. Wikipedia's progress bar (opens in a new tab) article covers the widget in general.

How do I make an indeterminate progress bar?

Leave out value: <progress></progress>. Browsers then animate a busy state, which tells the user work is going on without saying how much. Once you know the progress, set value and, if needed, max (default 1). To go back to indeterminate from JavaScript, call removeAttribute('value').

Related forms elements