Who it affects
Someone using a screen reader types a password, hears meter, 3, and has no idea whether that is strength, length, or something else.
Someone using a screen reader with a braille display reads a bare number with no label in the cell beside it.
Someone using voice control cannot ask for the meter by name to have its value read back.
Broken versus fixed
Both examples are live and rendered in a sandboxed frame. The broken one is deliberately broken.
Anyone looking can see the green bar means strength. A screen reader announces: meter, 3, or meter, 75 percent. The words Strength: good sit next to it but are not attached.
Announced: Password strength, meter, Good. aria-label gives the name and aria-valuetext turns 3 into a word. (Some screen readers still say progress bar or level for a meter; the name is spoken either way.)
Show the markup behind both examples
<style>body{font-family:system-ui;padding:16px;margin:0;font-size:14px}label{display:block;margin-bottom:4px}input{padding:5px;width:220px;display:block}.row{display:flex;align-items:center;gap:10px;margin-top:8px;width:232px}.m{flex:1;height:8px;border-radius:4px;background:#e2e8f0;overflow:hidden}.m span{display:block;height:100%;width:75%;background:#38a169}.t{font-size:13px;color:#4a5568}</style>
<label for="pw">Password</label>
<input id="pw" type="password" value="correct-horse-battery">
<div class="row">
<div class="m" role="meter" aria-valuemin="0" aria-valuemax="4" aria-valuenow="3"><span></span></div>
<span class="t">Strength: good</span>
</div>
<style>body{font-family:system-ui;padding:16px;margin:0;font-size:14px}label{display:block;margin-bottom:4px}input{padding:5px;width:220px;display:block}.row{display:flex;align-items:center;gap:10px;margin-top:8px;width:232px}.m{flex:1;height:8px;border-radius:4px;background:#e2e8f0;overflow:hidden}.m span{display:block;height:100%;width:75%;background:#38a169}.t{font-size:13px;color:#4a5568}</style>
<label for="pw">Password</label>
<input id="pw" type="password" value="correct-horse-battery">
<div class="row">
<div class="m" role="meter" aria-label="Password strength" aria-valuemin="0" aria-valuemax="4" aria-valuenow="3" aria-valuetext="Good"><span></span></div>
<span class="t">Strength: good</span>
</div>
Test it by hand in two minutes
- Inspect the element with role="meter". It needs aria-label, aria-labelledby pointing at visible text, or a native meter element with a label.
- In Chrome DevTools, select it and open the Accessibility pane. The computed Name should describe what is measured.
- Turn on VoiceOver (Cmd+F5) or NVDA and read through the area. You should hear the name, the role, and the value, in some order.
- Change the thing being measured (type more of the password) and check the announced value follows, and that aria-valuetext is updated if you use it.
The fix
<div role="meter" aria-valuemin="0" aria-valuemax="4" aria-valuenow="3"></div>
<div role="meter" aria-label="Password strength" aria-valuemin="0" aria-valuemax="4" aria-valuenow="3" aria-valuetext="Good"></div>
Name the thing being measured, not the widget. If there is visible text that says it, point at that with aria-labelledby instead of repeating it in aria-label.
Use the visible text as the name
<div role="meter" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100"></div>
<span>Storage used</span>
<div role="meter" aria-labelledby="st" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100"></div>
<span id="st">Storage used</span>
One source of truth. If the text changes, the name changes with it.
Native meter element
<div role="meter" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100"></div>
<label for="st">Storage used</label>
<meter id="st" min="0" max="100" value="62">62%</meter>
The native element handles range and value itself and takes a normal label.
Common mistakes
- Using aria-label="meter" or aria-label="bar", which names the widget rather than the measurement.
- Putting the name on the wrapper div rather than the element with the role.
- Using role="meter" for something that is loading; that is a progressbar.
- Setting aria-valuetext once and never updating it, so it says Weak while the bar shows Strong.
- Leaving the name in a title attribute, which most screen readers do not read on a meter.
WCAG criteria this rule maps to
axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:
- 1.1.1 Non-text Content (level A). Official W3C text.
The scanner can see a meter with an empty computed name. It cannot judge whether the name says what is measured, or whether aria-valuetext keeps up with the value. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.
Related rules
aria-progressbar-name
role="progressbar" tells a screen reader that something is in progress and how far along it is.
A
Required ARIA attributes must be provided for the role
aria-required-attr
Some ARIA roles only make sense with a state or value attached.
A
ARIA attributes must have valid values
aria-valid-attr-value
Each ARIA attribute accepts a particular kind of value: true or false, a number, a word from a short list, or the id of another element.
A
Form fields must have labels
label
Every input and textarea needs a label that is programmatically tied to it, not just sitting nearby.