Skip to main content

4.1.2 Name, Role, Value: what it requires and how to test it

Every interface component has to expose its name and role to assistive technology, and its states and values have to be readable and settable, with changes announced.

Level A · Added in WCAG 2.0 · Last reviewed October 18, 2026

What 4.1.2 requires

For all user-interface components, the name and role must be programmatically determinable. States, properties and values that users can set must be programmatically settable, and assistive technology must be notified of changes to them. Native HTML controls do this for you. Custom components built from divs have to do it with ARIA. This is a plain-language summary. The normative text, including every exception, is in the W3C Recommendation, with the W3C's explanation in Understanding 4.1.2 (opens in a new tab) [1][2].

Exceptions and scope:

  • None listed. It applies to all user-interface components, including those built with scripts.

Why it matters

This is the criterion behind most "I can't tell what this is" moments. An unnamed button is announced as "button". A custom checkbox without a role or state is just text. A menu toggle that doesn't expose aria-expanded never says whether it opened. Empty buttons were detected on 30.6% of the top million home pages in WebAIM's 2026 analysis [4].

Common failures

Buttons with no accessible name

Icon-only buttons with no text or label.

<!-- Fails -->
<button><svg>…</svg></button>

<!-- Better -->
<button aria-label="Close dialog"><svg aria-hidden="true">…</svg></button>

Custom controls without role or state

A div styled as a toggle.

<!-- Fails -->
<div class="toggle on" onclick="t()"></div>

<!-- Better -->
<button aria-pressed="true">Dark mode</button>

State changes not exposed

A disclosure that opens visually but never updates its state.

<!-- Fails -->
<button onclick="open()">Menu</button>

<!-- Better -->
<button aria-expanded="false" aria-controls="m">Menu</button> <!-- toggle aria-expanded -->

Form fields with no name

Payment fields that each announce "edit, blank".

<!-- Fails -->
<input autocomplete="cc-number">

<!-- Better -->
<label for="cc">Card number</label><input id="cc" autocomplete="cc-number">

Can automated testing check 4.1.2?

Partly, and better than for most criteria. Many missing names and invalid ARIA patterns are detectable. Correct state changes during use are not.

axe-core 4.13.0 ruleWhat it checks
button-name, input-button-namebuttons have discernible text
link-namelinks have discernible text
label, select-name, aria-input-field-name, aria-toggle-field-nameform fields have accessible names
aria-roles, aria-allowed-attr, aria-required-attr, aria-valid-attr, aria-valid-attr-value, aria-prohibited-attrARIA roles and attributes are valid and allowed
aria-hidden-focusaria-hidden elements don't contain focusable content
nested-interactiveinteractive controls aren't nested
frame-titleframes have accessible names
and othersaxe-core 4.13.0 maps 29 rules to 4.1.2 in total

What automation can't decide: Whether a name is meaningful ("button 3" passes the rule), whether state attributes update when the user acts, whether a custom widget behaves like the role it claims, and whether changes are announced.

A clean automated result is never proof that 4.1.2 is met. See why sites pass axe-core but fail real screen reader users.

How to test it by hand

  1. Tab to each control with a screen reader running. Listen for a name, a role (button, link, checkbox…) and any state (expanded, checked, selected).
  2. Operate each control and listen again: did the announced state change?
  3. Check custom widgets (tabs, menus, comboboxes, toggles) against the matching WAI-ARIA Authoring Practices pattern.
  4. Check that nothing focusable is hidden from assistive technology.

New to screen readers? Start with how to test a website with a screen reader and how to test keyboard-only navigation.

How Accessible helps (and where it stops)

Scanning runs the 4.1.2 rules on every URL on a paid plan. Journeys compute what each stop announces from the roles, names and states the browser exposes, and check them after every interaction, so a control whose state never changes, or a field that announces "edit, blank" at the payment step, is reported at the step it blocked. The example checkout on our journey page ends at exactly that, filed against 4.1.2 and 3.3.2. The assistant tools screen reader transcript shows every element's role, name and state in reading order.

Where it stops: Journeys simulate a screen-reader user in Chromium. They don't use NVDA, JAWS or VoiceOver, so how a specific screen reader handles a complex widget still needs testing with that screen reader. No automated tool, ours included, can certify that a criterion is met.

Sources

  1. Understanding Success Criterion 4.1.2: Name, Role, Value (opens in a new tab). W3C Web Accessibility Initiative. Accessed October 18, 2026.
  2. Web Content Accessibility Guidelines (WCAG) 2.2, Success Criterion 4.1.2 (opens in a new tab). W3C Recommendation. Accessed October 18, 2026.
  3. axe-core rule descriptions (opens in a new tab). Deque Systems, axe-core 4.13.0. Accessed October 18, 2026.
  4. The WebAIM Million: The 2026 report on the accessibility of the top 1,000,000 home pages (opens in a new tab). WebAIM, 2026. WAVE-detected errors on home pages only. Accessed October 18, 2026.
  5. WAI-ARIA Authoring Practices Guide (opens in a new tab). W3C. Accessed October 18, 2026.

Meeting a success criterion is not the same as legal compliance, which depends on the rules that apply to you. No automated tool can certify conformance.

Frequently asked questions

Does using ARIA guarantee 4.1.2 passes?

No. ARIA only changes what's exposed. The component also has to behave like its role and update its states. Native HTML elements are usually the safer choice.

Is aria-label enough to name a button?

It gives the button an accessible name, but if the button has visible text, the name should match or contain it (2.5.3 Label in Name), so voice-control users can say what they see.

Why do automated tools catch so many 4.1.2 issues?

Because a missing name or an invalid ARIA attribute is visible in the markup. Whether the component works when someone uses it isn't. That part needs a journey or a person.

Hear what every control in your checkout announces.

Check a page free, or run a journey that checks names and states after every step.