Do not build interactive controls from bare divs
F59 is a documented failure, so this page describes a way 4.1.2 Name, Role, Value gets broken rather than a way to pass it. The failure is script used to turn a div or a span into a control without giving it a role, which leaves an element behaving like a button and reporting itself as ordinary content. W3C's own example is a checkbox built from a span and two images. The part worth reading twice is what W3C says about fixing it halfway. Add keyboard access by hand and the problem does not go away. People still have no way to discover the control is a control, or to know which keys it answers to. These elements also do not raise the operating system events a real control raises, so assistive technology may never be told the user activated anything. The fix nearly always has one line in it. Use a button. Where a native element genuinely cannot do the job, ARIA4 is the technique for giving a hand-built control a role. Take that route and you own the role, the name, the state, the focus and the key handling yourself, permanently. The same mistake made with a link instead of a button is a separate failure, F42.
How we find it in an audit
W3C's test procedure is the one we run. Find every element carrying an event handler, check whether that element already has a native role, and check whether a fitting ARIA role has been put on it where there is none. The accessibility tree makes the answer visible in seconds, because a control that comes back as generic is the finding. Each one gets written up with the element, what it is missing, and which of the two routes applies. Swapping in a button and building the whole pattern by hand are very different amounts of work, and your team should know which one they are being asked for.
How affected users experience it
The div button is invisible twice over. The screen reader does not announce it as pressable, and the keyboard cannot reach it to press. So the listener hears the words buy now as ordinary text in the middle of a paragraph. Nothing suggests they are a control, and no key would do anything if the listener suspected. It is a door painted on a wall. The half-fixed version is nearly as bad, because a control that takes focus without announcing a role tells the listener something is here and nothing about what it is.
Passes vs. fails
Passes
<button type="button" onclick="placeOrder()">Place order</button>
<!-- where a native element really cannot be used, ARIA4 is the route -->
<div role="button" tabindex="0" onclick="placeOrder()" onkeydown="enterOrSpace(event)">Place order</div>Fails
<span class="looks-like-button" onclick="placeOrder()">Place order</span>How this gets tested
The W3C publishes test rules that define what a checker looks for here.
- Image button has non-empty accessible nameA tool can check this
- Link has non-empty accessible nameA tool can check this
- ARIA attribute is defined in WAI-ARIAA tool can check this
- ARIA state or property has valid valueA tool can check this
- Element with role attribute has required states and propertiesA tool can check this
- Form field has non-empty accessible nameA tool can check this
- Role attribute has valid valueA tool can check this
- ARIA state or property is permittedA tool can check this
- Button has non-empty accessible nameA tool can check this
- Element with aria-hidden has no content in sequential focus navigationA tool can check this
- Element with presentational children has no focusable contentA tool can check this
- Menuitem has non-empty accessible nameA tool can check this
- Summary element has non-empty accessible nameA tool can check this
- Iframe element has non-empty accessible nameA tool can check this
- Iframe elements with identical accessible names have equivalent purposeA tool finds candidates, you decide
The other techniques filed under this rule
23 guides on this site are filed under 4.1.2 Name, Role, Value. W3C documents this one as a failure of that rule, so it describes a way the rule gets broken rather than a way to pass it.
- ARIA4sufficientGive custom widgets a real ARIA role
- ARIA5sufficientExpose widget state with ARIA attributes
- ARIA14sufficientLabel icon-only controls with aria-label
- ARIA16sufficientName controls from visible text with aria-labelledby
- G10sufficientBuild custom components on accessibility-supported tech
- G108sufficientExpose name, role, and changes through markup
This guide is our interpretation of W3C technique F59: Failure of Success Criterion 4.1.2 due to using script to make div or span a user interface control in HTML without providing a role for the control. W3C publishes its techniques as guidance rather than as the standard, and says so on every one of them. The success criterion is what conformance is measured against, and a technique is one documented way to meet it.