Who it affects
Someone posting in a community group's custom comment box with a screen reader lands in a contenteditable div with role="textbox" and hears edit text. They do not know whether they are writing a comment, a reply or a report.
Someone with low vision who relies on spoken labels at high zoom cannot see the nearby heading and the custom field does not announce it, so they type into the wrong box.
Someone using voice control says click comment and nothing happens, because the custom field has no name to match.
Broken versus fixed
Both examples are live and rendered in a sandboxed frame. The broken one is deliberately broken.
Tab in with a screen reader on: edit text, multi-line. No name. The heading above is not connected.
Announced: Reply to Priya, edit text, multi-line.
Show the markup behind both examples
<style>body{font-family:system-ui;padding:16px;margin:0}.box{border:1px solid #888;border-radius:6px;padding:10px;min-height:50px;width:280px;font-size:15px}.box:focus{outline:3px solid #1e5aa8}</style>
<h2 style="font-size:17px;margin:0 0 8px">Reply to Priya</h2>
<div class="box" role="textbox" contenteditable="true" aria-multiline="true"></div>
<style>body{font-family:system-ui;padding:16px;margin:0}.box{border:1px solid #888;border-radius:6px;padding:10px;min-height:50px;width:280px;font-size:15px}.box:focus{outline:3px solid #1e5aa8}</style>
<h2 id="reply-h" style="font-size:17px;margin:0 0 8px">Reply to Priya</h2>
<div class="box" role="textbox" contenteditable="true" aria-multiline="true" aria-labelledby="reply-h"></div>
Test it by hand in two minutes
- In DevTools, search the Elements panel for role="textbox", role="combobox", role="listbox", role="slider" and role="spinbutton". Each match needs aria-label or aria-labelledby.
- Select the element in DevTools and open the Accessibility pane. The Name row should show real words, not an empty value.
- Turn on VoiceOver (Cmd+F5) or NVDA and Tab to the custom field. You should hear the purpose before the role, for example Reply to Priya, edit text.
- Try clicking the visible text you expect to be the label. Unlike a real label element, it will not focus the field, so make sure the aria link is there instead.
The fix
<div role="textbox" contenteditable="true"></div>
<h2 id="reply-h">Reply to Priya</h2>
<div role="textbox" contenteditable="true" aria-labelledby="reply-h"></div>
Point at visible text with aria-labelledby when it exists, so sighted and screen reader users get the same words. Use aria-label when there is no visible text to point at.
Custom combobox
<div role="combobox" aria-expanded="false">Any time</div>
<span id="when">Appointment time</span>
<div role="combobox" aria-expanded="false" aria-labelledby="when">Any time</div>
The current value (Any time) is not the name. The name says what is being chosen.
Slider
<div role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40"></div>
<div role="slider" aria-label="Volume" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40"></div>
Sliders rarely have visible text, so aria-label is usually the right tool.
Use a real input instead
<div role="textbox" contenteditable="true"></div>
<label for="reply">Reply to Priya</label>
<textarea id="reply"></textarea>
If you do not need rich text, a native textarea gets labelling, focus and keyboard behaviour for free.
Common mistakes
- Adding a label element with a for attribute pointing at a div; label only names form controls, not div or span elements.
- Using placeholder-style text inside the div as the name; it vanishes when typing starts.
- Putting the name in title, which is not reliably spoken.
- Pointing aria-labelledby at an id that does not exist, often after a rename.
- Using the current value of a combobox as its name.
WCAG criteria this rule maps to
axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:
- 4.1.2 Name, Role, Value (level A). Official W3C text.
The scanner can see an element with an ARIA input role that has no aria-label, aria-labelledby or title, and can tell when aria-labelledby points at nothing. It cannot judge whether the name describes what the field is for. 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
label
Every input and textarea needs a label that is programmatically tied to it, not just sitting nearby.
A
ARIA toggle fields must have an accessible name
aria-toggle-field-name
Elements with role="switch", role="checkbox", role="radio", role="menuitemcheckbox" or role="menuitemradio" are toggles: they are on or off, checked or not.
A
Select menus must have an accessible name
select-name
A select element is a drop-down list of choices.
A
ARIA roles must be valid
aria-roles
The role attribute only accepts names from the ARIA list: dialog, button, tab, listbox and so on.