WCAG 4.1.2 Name, Role, Value: Fix Custom Component Accessibility
Last updated: 2026-03-22
What This Criterion Requires
WCAG 4.1.2 requires that for all user interface components, the name and role can be programmatically determined, states, properties, and values can be programmatically set, and notification of changes to these items is available to user agents, including assistive technologies. This criterion ensures that assistive technologies can accurately present and interact with every UI component on the page. Native HTML elements like buttons, links, inputs, and selects automatically satisfy this requirement because browsers expose their semantics to the accessibility tree. However, custom components built with divs, spans, or other generic elements require explicit ARIA roles, names, and state management to be accessible. Common violations include custom dropdowns without combobox or listbox roles, toggles without the switch role and aria-checked state, tabs without tablist/tab/tabpanel roles, accordions that do not communicate expanded or collapsed state, and any interactive custom component that does not update its ARIA state when user interaction changes its visual state.
Why It Matters
Assistive technologies like screen readers, voice control software, and switch navigation systems rely on the accessibility tree to understand what UI components are, what they are called, and what state they are in. When a custom component does not expose this information correctly, assistive technology users encounter an interface that is fundamentally broken: a custom dropdown may be announced simply as 'clickable' with no indication that it is a selection control, a custom toggle may not communicate whether it is on or off, and a custom tab interface may present as a collection of meaningless links. This is not just confusing but makes the interface inoperable. As web applications become more complex with custom components replacing native HTML elements, this criterion becomes increasingly critical. It is the technical backbone of accessible custom widget development. Using native HTML elements wherever possible is the best strategy, as they provide built-in accessibility semantics without additional work. When custom components are necessary, rigorous ARIA implementation and state management are required.
Common Failures and How to Fix Them
Custom dropdown without proper roles and states
A custom select dropdown is built with divs but does not use ARIA roles to communicate its purpose or aria-expanded to indicate its open/closed state. Screen readers announce it as generic text.
<div class="custom-select" onclick="toggleDropdown()">
<div class="selected-value">Choose an option</div>
<div class="options" id="dropdown-options">
<div onclick="selectOption('opt1')">Option 1</div>
<div onclick="selectOption('opt2')">Option 2</div>
<div onclick="selectOption('opt3')">Option 3</div>
</div>
</div> <div role="combobox" aria-expanded="false" aria-haspopup="listbox" aria-labelledby="select-label" tabindex="0">
<span id="select-label">Choose an option</span>
<ul role="listbox" id="dropdown-options" hidden>
<li role="option" id="opt1" tabindex="-1">Option 1</li>
<li role="option" id="opt2" tabindex="-1">Option 2</li>
<li role="option" id="opt3" tabindex="-1">Option 3</li>
</ul>
</div> Toggle switch without role or state
A custom toggle switch built with a div and CSS does not communicate its role (switch or checkbox) or its current state (checked/unchecked) to assistive technologies.
<div class="toggle" onclick="toggleDarkMode()">
<div class="toggle-track">
<div class="toggle-thumb"></div>
</div>
<span>Dark Mode</span>
</div> <button role="switch" aria-checked="false" onclick="toggleDarkMode(this)">
<span class="toggle-track">
<span class="toggle-thumb"></span>
</span>
Dark Mode
</button> Accordion that does not expose expanded/collapsed state
An accordion widget uses buttons to toggle content sections but does not communicate whether each section is expanded or collapsed. Screen reader users cannot tell which sections are open.
<div class="accordion">
<div class="accordion-header" onclick="toggleAccordion('section1')">
Shipping Information
</div>
<div class="accordion-panel" id="section1">
<p>We ship to all 50 states...</p>
</div>
</div> <div class="accordion">
<h3>
<button aria-expanded="false" aria-controls="section1" onclick="toggleAccordion(this)">
Shipping Information
</button>
</h3>
<div class="accordion-panel" id="section1" role="region" aria-labelledby="section1-btn" hidden>
<p>We ship to all 50 states...</p>
</div>
</div> How to Test
- Open the browser's Accessibility Inspector (Chrome DevTools > Elements > Accessibility pane) and verify that every interactive custom component has a correct role, accessible name, and appropriate state properties.
- Interact with each custom component (toggle, dropdown, accordion, tab, carousel) and confirm that ARIA state attributes (aria-expanded, aria-checked, aria-selected, aria-pressed) update correctly when the visual state changes.
- Navigate all custom components with a screen reader and verify they are announced with the correct role and state (e.g., 'Dark Mode, switch, off' rather than just 'Dark Mode').
- Run axe DevTools to detect missing roles, names, and ARIA attribute issues on custom interactive components.
CMS-Specific Guidance
This criterion commonly causes issues on these platforms:
Further Reading
Related WCAG Criteria
Get our free accessibility toolkit
We're building a simple accessibility checker for non-developers. Join the waitlist for early access and a free EAA compliance checklist.
No spam. Unsubscribe anytime.