Showing task progress with HTML progress
For an upload, download, or any other task with measurable progress, HTML already has the right element. A <progress> element needs both opening and closing tags:
<progress value="10" max="100"></progress>
value must be zero or greater and no larger than max. If max is omitted, it defaults to 1; when present, it must be greater than zero. Leave out value when the amount of progress is unknown and you need an indeterminate indicator.
Browser support was already good in 2020, with support beginning in Safari 6 and Internet Explorer 10. Use <meter> instead when you are showing a measurement, such as disk usage, rather than the completion of a task.
Styling is browser-specific
Browsers give <progress> their own native appearance. The element selector handles the outer box:
progress {
background-color:#ddd;
border:0;
height:20px;
border-radius:5px;
}
The filled portion needs vendor-specific pseudo-elements:
/* Firefox */
progress::-moz-progress-bar { background: #ddd; }
/* WebKit & Blink */
progress::-webkit-progress-bar { background: #ddd; }
progress::-webkit-progress-value { background: #000; }
Native styling is a reasonable default, and I would keep it unless the bar genuinely clashes with the rest of the interface. If you customise it, check the result in more than one browser.
Enjoyed reading this?
If you found this article helpful, consider supporting my writing. Every little bit helps keep this blog going.
Related articles
- The HTML Details That Make Forms More Accessible
Build clearer forms with visible labels, autocomplete, connected help and errors, fieldsets, and visible focus.
- When a Control Needs aria-label
Use aria-label for genuinely unlabelled controls while keeping visible text and native elements as the first choice.
- When CSS Layout Order Stops Matching the HTML
Keep Grid and Flexbox layouts aligned with the HTML order so keyboard focus and screen reader reading do not jump around the page.