Required ARIA attribute missing (aria-required-attr)

The aria-required-attr rule flags an element whose ARIA role needs a state or property that is not there – a role="switch" without aria-checked, a role="slider" without aria-valuenow. The role tells assistive technology what the control is; without its required state nobody can tell whether it is on, off or at 40%. The fix is to add the attribute and keep it in step with the control.

What the rule means

WAI-ARIA 1.2 lists, for each role, the states and properties an author must provide [3]. axe-core checks these:

  • checkbox, radio, switch, menuitemcheckbox, menuitemradio – aria-checked;
  • slider, scrollbar, meter and a focusable separator – aria-valuenow;
  • combobox – aria-expanded and aria-controls;
  • heading – aria-level.

The rule only looks at roles written in a role attribute. Native HTML already carries these states: an <input type="checkbox"> has a checked state, an <h2> has a level, and an <input type="range"> has a value. Three exceptions are built in. A combobox that is closed (aria-expanded="false") does not need aria-controls yet. A slider with aria-valuetext is accepted without aria-valuenow. A separator that cannot be focused is a plain divider and needs no value.

The rule does not check whether the value is correct, or whether it changes when the control is used.

Who is affected

Screen reader users hear "switch" or "slider" and then nothing about its state, so they cannot tell whether notifications are on or how loud the volume is. People using voice control or switch access may be able to operate the control but get no feedback that it changed. A missing aria-level also removes a heading from the heading outline many screen reader users navigate by.

Why the check fails

  • Custom toggles in design systems: a <button role="switch"> styled as a pill, with the state kept only in a CSS class.
  • Hand-made sliders from a carousel or price-filter plugin that set aria-valuemin and aria-valuemax but never the current value.
  • Comboboxes from autocomplete libraries that add role="combobox" but leave out aria-expanded.
  • role="heading" on a <div> in a page builder, without aria-level.
  • Server-rendered markup that expects a script to add the state later, while the script fails or has not run yet.
  • A role added to fix another finding without reading which attributes come with it.

How to fix it

  1. Check which states the role requires in WAI-ARIA 1.2 [3] or the matching pattern in the ARIA Authoring Practices Guide [5].
  2. Add them in the component, with an honest starting value.
  3. Update the value every time the control changes.
  4. Better still, use the native element: <input type="checkbox" role="switch"> or <input type="range"> carry their state without any ARIA to maintain.
<!-- Before: a switch with no state and a slider with no value -->
<div class="settings">
  <span id="notify-label">Email notifications</span>
  <button class="toggle" role="switch" aria-labelledby="notify-label"></button>
  <span id="volume-label">Volume</span>
  <div class="range" role="slider" tabindex="0" aria-labelledby="volume-label"
       aria-valuemin="0" aria-valuemax="100"></div>
</div>
<!-- After: each role has the state it requires -->
<div class="settings">
  <span id="notify-label">Email notifications</span>
  <button class="toggle" role="switch" aria-checked="false" aria-labelledby="notify-label"></button>
  <span id="volume-label">Volume</span>
  <div class="range" role="slider" tabindex="0" aria-labelledby="volume-label"
       aria-valuemin="0" aria-valuemax="100" aria-valuenow="40"></div>
</div>

The state has to follow the control. For the switch:

// Flip the state in the same handler that flips the setting
toggle.addEventListener('click', () => {
  const on = toggle.getAttribute('aria-checked') === 'true'
  toggle.setAttribute('aria-checked', String(!on))
})

How to test it manually

  1. Select the control in your browser's developer tools and open the Accessibility pane: it lists the role and the states the browser exposes.
  2. Operate the control with the keyboard – Space on a switch, arrow keys on a slider – and check that the state in the pane changes.
  3. With a screen reader such as NVDA (free) or VoiceOver, check that the state is announced when you reach the control and again when it changes.
  4. What the rule cannot see: a state that is present but wrong, or one that never updates.

4.1.2 Name, Role, Value, Level A: the state of a user interface component must be available to assistive technology. For a heading without a level, 1.3.1 Info and Relationships is affected as well.

How Reviseberg reports it

Reviseberg runs aria-required-attr on every crawled page. The issue list shows the rule with its severity, WCAG 4.1.2 and Level A, the number of elements and pages, and the points a fix gets you back; the detail view shows the selector, the HTML snippet and every affected page. A switch or slider usually comes from one component, so the same finding tends to appear on many pages and one fix clears them together. Findings can be marked "ignore", "can't fix" or "false positive" with a reason, and every decision is logged. A clean run does not settle 4.1.2 – whether the state keeps up with the control needs a person operating it.

  • undefined – the attribute is there, but its value is not allowed.
  • undefined – an attribute the role does not support.
  • undefined – a role that needs certain child roles, such as a listbox without options.

Check your components for missing ARIA states – get a free scan

Frequently asked questions

Does <input type="checkbox"> need aria-checked?

No. The native checkbox exposes its checked state itself. Adding aria-checked would only create a second value that can drift from the real one.

Why does a combobox pass without aria-controls?

When it is closed (aria-expanded="false"), the popup may not exist yet, so axe does not ask for the reference. Once it opens, aria-controls must point to the list.

Is aria-valuetext enough on a slider?

axe accepts it. Screen readers read aria-valuetext in place of the number, which helps for values such as "€250" or "Medium". Keep aria-valuenow as well where there is a number.

Can I set the state only after the script loads?

The rule sees the page after it has loaded, so a state added by a script that ran is counted. A state that only appears on the first click is not.

Sources

  1. W3C, Understanding SC 4.1.2 Name, Role, Value – https://www.w3.org/WAI/WCAG22/Understanding/name-role-value
  2. Deque University, axe-core 4.13 rule aria-required-attr – https://dequeuniversity.com/rules/axe/4.13/aria-required-attr
  3. W3C, Accessible Rich Internet Applications (WAI-ARIA) 1.2 – https://www.w3.org/TR/wai-aria-1.2/
  4. W3C, ACT rule: Element with role attribute has required states and properties – https://www.w3.org/WAI/standards-guidelines/act/rules/4e8ab6/
  5. W3C, ARIA Authoring Practices Guide: Switch pattern – https://www.w3.org/WAI/ARIA/apg/patterns/switch/
  6. W3C, ARIA Authoring Practices Guide: Slider pattern – https://www.w3.org/WAI/ARIA/apg/patterns/slider/

See what a scan finds on your site

One page in about thirty seconds, no email needed. The full report covers up to 100 pages and a keyboard journey.