Lesson 46 of 55 · HTML
Using `<meter>` and `<progress>` for UI Elements
Duration: 9 min
Native UI Indicators – <meter> & <progress>
<label for='fuel'>Fuel level</label>
<meter id='fuel' min='0' max='100' low='20' high='80' optimum='50' value='45'>45%</meter>
<label for='upload'>Upload progress</label>
<progress id='upload' max='100' value='70'>70%</progress>
<meter>
- Represents a scalar measurement within a known range (e.g., battery, rating).
- Supports
low,high, andoptimumattributes to visually indicate status. - Browsers render a simple bar; you can style it with vendor‑specific pseudo‑elements (see below).
<progress>
- Shows task completion (file upload, form submission).
- Updated via JavaScript:
const prog = document.getElementById('upload');
let percent = 0;
const interval = setInterval(() => {
percent += 10;
prog.value = percent;
if (percent >= 100) clearInterval(interval);
}, 500);
valuemay be omitted for indeterminate progress (spinner).
Styling (vendor‑specific)
/* Chrome & Safari */
progress::-webkit-progress-bar { background: #eee; }
progress::-webkit-progress-value { background: #3b82f6; }
/* Firefox */
progress::-moz-progress-bar { background: #3b82f6; }
Make sure the styling respects prefers‑reduced‑motion for users who disable animations.
Quick checklist for native UI elements
<meter>used for scalar values with propermin,max, andvalue? ✅<progress>updated via JavaScript and handling indeterminate state? ✅- Styling applied with appropriate vendor prefixes? ✅
- Accessibility labels (
aria-labelor<label for>) present? ✅ prefers-reduced-motionrespected in any animated styling? ✅
Tip: Prefer native elements over custom JS‑only progress bars because they inherit keyboard and screen‑reader support automatically.