Forms & Input
Meter
AvailableA read-only indicator showing a quantity within a known range, such as disk usage.
What Is a Meter?
A meter is a display-only indicator that visually represents thecurrent value within a known range. Common uses include disk usage, battery level, password strength, and stock levels.
Meter vs. Progressbar (Important Distinction)
A meter represents a static measurement — "how much out of a known range right now" (e.g., disk at 72%). A progress bar represents progress toward completion — "how far along is this task" (e.g., downloading). Use role="progressbar" for task progress and meter for a point-in-time measurement.
Why Does Accessibility Matter?
- Screen reader users. If you just draw a colored bar with a
<div>,nothing is conveyed to people who can't see the screen — neither the value "72%" nor the meaning "Disk Usage." The role, value, and range must be exposed in a way that assistive technologies can read. - Don't rely on color alone. Indicating status only through color (e.g., "red = danger") doesn't work for people with color vision deficiencies or in monochrome environments. Always include the numeric value (72%) or supplementary text (28% remaining) as well.
Tip
A meter is display-only and non-interactive. It is not something the user changes, so no keyboard interaction is needed (and it doesn't need to be focusable). If users need to change the value, that's a slider, not a meter.
Live Demo (Recommended Implementation)
Below is a native <meter> element. It's a display for reading status, not something you interact with.Try checking the readout with a screen reader.
Note: This is display-only, so Tab won't focus it. A screen reader will announce something like 'Disk Usage, 72%.'
Note
Setting low / high / optimum on <meter> lets the browser color-code "good / caution / danger" states. However, color is only supplementary — the meaning must always be conveyed through value (and accompanying text).
Keyboard Interaction
This pattern has no specific keyboard interactions.
Note
If you need "arrow keys to change the value," then what you need is aslider (role="slider"), not a meter. Don't confuse the two roles.
Required WAI-ARIA Roles & Properties
| Target | Attribute / Role | Meaning |
|---|---|---|
| Native meter | <meter min max value> + <label for> | Role, value, and range are provided automatically. Use label to give it a name. |
| Custom meter element | role="meter" | Conveys to assistive technologies that this is a measured value display. |
| Custom meter element | aria-valuemin / aria-valuemax | Defines the range (minimum and maximum). A known range is a prerequisite for meter. |
| Custom meter element | aria-valuenow | The current value. Update programmatically when the value changes (not via user interaction). |
| Custom meter element | aria-valuetext | Provides a human-readable representation such as "72%" or "28% remaining" (optional but recommended). |
| Custom meter element | aria-label / aria-labelledby | The accessible name describing what the meter measures (e.g., "Disk usage"). |
| Custom meter element | No tabindex | Display-only, so no focus is needed. Do not confuse with role="slider". |
Implementation: Recommended Pattern (Good)
Good / Recommended
Start with the native <meter>. Just associate a label and you get the role, value, range, and color coding for free.
Markup:
<label for="disk">Disk Usage</label>
<meter
id="disk"
min="0"
max="100"
low="60"
high="85"
optimum="0"
value="72">72%</meter>
<!-- The "72%" inside is fallback text for browsers that don't support <meter> -->Only when native <meter> can't meet design requirements should you build a custom one with role="meter".No focus or keyboard handling is needed — just update the attributes when the value changes.
<!-- Only build a custom meter when native <meter> can't meet design requirements -->
<span id="disk-label">Disk Usage</span>
<div role="meter"
aria-labelledby="disk-label"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="72"
aria-valuetext="72% (28% remaining)"
class="meter">
<span class="meter-fill" style="width:72%"></span>
</div>
<!--
This is display-only, so don't add tabindex or role="slider".
When the value changes, just update aria-valuenow / aria-valuetext.
-->Anti-Pattern (Bad)
Below is a colored bar drawn with plain <div> elements.It looks like a meter visually, but a screen reader can't perceive it at all.
Note: A screen reader sees no role or value here, so the fact that 'Disk Usage is at 72%' is completely invisible (it's treated as a decorative bar).
<!-- ❌ Anti-pattern: just a colored div -->
<span>Disk Usage</span>
<div class="track">
<div class="fill" style="width:72%"></div>
</div>
<!--
No role="meter" or <meter> element, so it's not recognized as a measurement.
No aria-valuenow or range, so "72%" is never announced.
Color is the only state indicator (invisible to people with color vision deficiencies).
-->Bad / Avoid
Problems with this implementation:
- No role — Without
role="meter"or a<meter>element, it's not recognized as a measurement. - No value or range — Without
aria-valuenow / valuemin / valuemax, "72%" is never announced. - No accessible name — The bar and "Disk Usage" are not programmatically associated.
- Color-only — Without numeric or text supplements, the information doesn't reach people who can't see color.
Implementation Checklist
- Confirmed this is a "current quantity within a known range" and not progress (not confused with progressbar)
- Considered using the native meter element first (highest priority)
- The meter has an accessible name (label for or aria-label / aria-labelledby)
- For custom implementations, role="meter" + aria-valuemin / aria-valuemax / aria-valuenow are present
- aria-valuenow (and aria-valuetext) are updated when the value changes
- Display-only, so tabindex is not applied (no keyboard interaction)
- State is conveyed not only by color but also by numeric values or text
Source (English):Meter Pattern — W3C APG(opens in a new tab)