Skip to main content
WCAGrules
Quick navigation

Name, Role, Value

Every control has to tell assistive technology three things about itself. What it is called, what kind of control it is, and what state it is in right now. There is a fourth part the short version usually drops, and it matters. Where a value is one the user can set, such as a slider position or a checked box, that value has to be settable from outside rather than only readable. Any change to it has to fire a notification as well. Native HTML gives you the role and the state for free. It does not give you a name for free, because a button with no text and no label has no name at all. A control built out of a div gives you none of the four until somebody writes them in by hand.

Why it matters

This is the contract between your interface and every assistive technology that will ever touch your site. Break it and the dropdown that looks fine on screen is, to a screen reader, a lump of text with no way in. Your screen reader says button. Just button. Now pick the one that empties your cart. Sites built on component frameworks live or die on this rule, because on those sites almost every control started life as a div rather than as a button. And it reaches past screen readers, since a voice-control user activates a control by saying its name, and a control with no name has no name to say.

Who this rule protects

Screen reader users hear nothing useful, or hear only that something is clickable, which is what VoiceOver says about any element carrying a click handler. Either way they cannot tell what the control does, or whether it is a control at all. Voice-control users cannot speak the name to activate it, because there is no name to speak. And a user working a slider through their own assistive technology cannot move it when the value is exposed but not settable. That satisfies half this rule and fails the other half.

How to check it yourself

  1. Open the accessibility tree in your browser's developer tools, which is the stripped-down version of the page that assistive technology actually reads, and find each custom control on it. Dropdowns, toggles, date pickers and hamburger menus are the usual suspects.
  2. Check three things on each one. A name that says what it is called, a role that says what kind of control it is, and a state that changes when the control changes, such as expanded, checked or selected.
  3. Check the fourth thing too, which is whether a value the user can set can actually be set from outside. A slider a screen reader can read and cannot move satisfies half this rule and fails the other half.
  4. Tab to each control with a screen reader running and confirm what you hear matches what you see. Confirm it announces itself when focus lands on it as well. Whether a control has focus is a state under this rule, so a custom widget that takes focus silently fails on that alone.
  5. Watch out for the text input whose only label is placeholder text. It usually passes this criterion, because the name computation falls back to the placeholder when nothing else supplies a name. It fails 3.3.2 instead, since a label that disappears when you type is not presented to all users. That difference is the commonest reason a scan report and an auditor disagree about the same field.
  6. Look inside your buttons. A button with a link or another button in it fails. A control like that is not supposed to expose anything focusable underneath, and there is an automated rule that looks for exactly this.
  7. Check the iframes. An iframe is a user interface component here too, and an embedded checkout, map or video player with no title is the usual finding.

Failures we see most often

  • A div with a click handler and no role is announced as plain text, or skipped altogether. The deeper problem is not silence on arrival. A div does not fire the operating system events a real control fires, so assistive technology may not be told anything happened when the user activates it either.
  • An icon-only button announces as button and nothing else, so a user hears that something is pressable without hearing what it does.
  • A control has visible label text and no accessible name. It reads fine, and a speech-input user cannot say its name to operate it, because there is no name to say. Voice software can usually reach it another way, by numbering the things on screen or overlaying a grid, and needing the fallback is the finding.
  • A custom toggle never says whether it is on or off, because its state lives in a CSS class and assistive technology cannot read CSS classes.
  • An aria-label gets added to a bare div to fix a missing name and nothing changes. A div's implicit role is generic, ARIA prohibits naming that role outright, and a browser is entitled to drop the attribute. What the element needs is a role that permits naming, whether that comes from a native element or from an explicit role attribute.
  • A phone number is split into three inputs under one group label, and the three parts carry no names of their own. A screen reader user reaches the second box with nothing to say what belongs in it.
  • A link contains only an image and the image has no alt text, so the whole link has an empty name and announces as a link to nowhere.
  • Two elements share an id and an aria-labelledby points at it, so one control ends up named after the other one's label. Old scan reports file duplicate ids under 4.1.1 Parsing, a criterion WCAG 2.2 removed, and W3C's own note says to report the consequence under whichever criterion it actually breaks. Here, that is this one.

Who this one is for

Read from this rule's own note above, so the grouping and the note cannot disagree.

The ARIA roles behind this rule

Most failures of this criterion are an ARIA role that was declared without the thing it requires. Of the 94 roles, 34 oblige you to supply a state, a particular parent, or particular children. Every ARIA role, and what each one obliges sets out which.

How this one is tested

We list 15 ACT rules against 4.1.2. Each one defines exactly what a checker looks at, which is how automated tools decide what to flag. Each one also checks a slice, so passing every rule here is not the same as meeting the criterion, and a rule can be proposed rather than approved or need a person to finish it. The note beside each says which.

How to fix it

  • Use the native element wherever one exists. A button, a select and an input carry the right role and keep their own state with no code from you. The one thing they still need is a name, and that comes from their text content or a label.
  • When a custom widget is unavoidable, give it a role that permits naming before you worry about the name. An aria-label does nothing on a generic role, whichever order the attributes were typed in, and that is why so many attempted fixes change nothing at all. A native button needs no role attribute, because it already has one that can be named.
  • Keep the state attributes in step with what the interface is doing, every time it changes. aria-expanded on a disclosure, aria-checked on a toggle, aria-selected on a tab. A state that is right on load and wrong afterwards is worse than no state at all.
  • Give every icon-only control a name that says what it does rather than what it looks like. Open cart, not shopping trolley.
  • Watch what an aria-label does to visible text. The name computation prefers an author-supplied label over the element's own content. So an aria-label on a button that already has words in it silently replaces those words, and a voice-control user reading the button aloud no longer reaches it.
  • Take focusable things out of buttons and tabs and make them siblings instead, since a control that owns its own children is not meant to expose them separately.
  • Give every iframe a title that says what it holds, such as Payment or Store locator, so a screen reader user knows what they have just stepped into.
Step-by-step fix guides (23)

Passes vs. fails

A general illustration of the pattern rather than a test of 4.1.2. Passes: name, role, and state exposed. Fails: a control with no identity.

Passes

The same control ships as <button aria-label="Open cart"><img src="cart.svg" alt=""></button>, so it carries the button role, an accessible name of Open cart, and its own focus and activation behaviour with no extra code. A control that stays switched on is a different job, and that one needs its state written and kept in step by hand.

Fails

The cart control ships as <div class="btn" onclick="openCart()"><img src="cart.svg"></div>. No role, no name, no state, and to a screen reader it is a picture with nothing to say.

In audits and lawsuits

This is the defining criterion for React and Vue-era sites, where nearly every interactive element started life as a div. Our audits routinely trace complaints such as could not select a size straight back to one of them. It is also the criterion that shows most plainly what a scanner can and cannot do for you. W3C files fifteen test rules under this one criterion, more than under any other, and ten of them name it as the thing they test. Seven of those ten ask only whether a control has an accessible name, and every one of the seven passes on any string that is not empty. Not one of them reads the name and asks whether it describes the control, so a button called button clears the button rule and a link called link clears the link one. Clearing a rule is not clearing the criterion. Six of those seven naming rules are written for links, form fields, image buttons, frames, menu items and summaries, so none of them was ever looking at your button. The rule about elements whose children are meant to be presentational was, and it fails that same button the moment something focusable sits inside it. That is not a complaint about the rules, which are exact about what they test. It is why a green report here proves less than it looks like it proves. And it is why our findings carry the pattern to apply rather than a count of the things a tool noticed.

Go somewhere useful

Find tools, resources and your workspace.

29 destinations