ARIA Rule

Required ARIA attributes must be provided for the role aria-required-attr

Some ARIA roles only make sense with a state or value attached. A switch is on or off (aria-checked), a slider is at a number (aria-valuenow), a heading has a level (aria-level), a combobox is open or closed (aria-expanded). Give an element the role without the attribute and a screen reader can say what it is but not what it is doing, which is the half that mattered.

Websight reports this as Required ARIA attributes must be provided

Who it affects

Someone using a screen reader lands on a dark mode toggle and hears switch with no on or off. They cannot tell what will happen if they press it.

Someone using a braille display reads swch and nothing more, with no state cell beside it.

Someone using switch access or a sip-and-puff device with a screen reader has to activate the control blind, then listen again, then possibly undo it, which is three slow actions instead of one.

Broken versus fixed

Both examples are live and rendered in a sandboxed frame. The broken one is deliberately broken.

Broken

The toggle is clearly on. A screen reader announces: Dark mode, switch, off, or just Dark mode, switch. Without aria-checked the browser has no state to report and may guess.

Fixed

Announced: Dark mode, switch, on. In a real page your script flips aria-checked each time the button is pressed; this demo is static.

Show the markup behind both examples
Broken
<style>body{font-family:system-ui;padding:16px;margin:0}.row{display:flex;align-items:center;gap:12px}.sw{width:44px;height:24px;border-radius:12px;border:0;background:#2b6cb0;position:relative;padding:0;cursor:pointer}.sw::after{content:"";position:absolute;top:3px;left:23px;width:18px;height:18px;border-radius:50%;background:#fff}</style>
<div class="row">
  <span id="dm">Dark mode</span>
  <button class="sw" role="switch" aria-labelledby="dm"></button>
</div>
Fixed
<style>body{font-family:system-ui;padding:16px;margin:0}.row{display:flex;align-items:center;gap:12px}.sw{width:44px;height:24px;border-radius:12px;border:0;background:#2b6cb0;position:relative;padding:0;cursor:pointer}.sw::after{content:"";position:absolute;top:3px;left:23px;width:18px;height:18px;border-radius:50%;background:#fff}</style>
<div class="row">
  <span id="dm">Dark mode</span>
  <button class="sw" role="switch" aria-checked="true" aria-labelledby="dm"></button>
</div>

Test it by hand in two minutes

  1. Inspect the element with the role attribute and list its aria- attributes.
  2. Check the role's required attribute is there: switch and checkbox need aria-checked, slider and spinbutton need aria-valuenow, heading needs aria-level, combobox needs aria-expanded, scrollbar needs aria-controls and aria-valuenow.
  3. Turn on VoiceOver (Cmd+F5) or NVDA, Tab to the control and listen for the state after the role: on or off, a number, a level.
  4. Operate the control and listen again. The state should change in the announcement, not just on screen.

The fix

Before
<button role="switch" aria-labelledby="dm"></button>
After
<button role="switch" aria-checked="true" aria-labelledby="dm"></button>

Add the attribute and keep it updated in the same place your code changes the visual state. If you would rather not manage state by hand, a native input type="checkbox" with role="switch" handles aria-checked for you.

Slider without a value

Before
<div role="slider" aria-label="Volume" tabindex="0"></div>
After
<div role="slider" aria-label="Volume" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40" tabindex="0"></div>

aria-valuenow is required. aria-valuemin and aria-valuemax default to 0 and 100 but stating them avoids surprises. A native input type="range" does all of this.

Heading role without a level

Before
<div role="heading">Delivery</div>
After
<h2>Delivery</h2>

role="heading" needs aria-level. Usually the better fix is a real h2 or h3, which carries the level for free.

Common mistakes

  • Adding the attribute with a fixed value and never updating it, so it is always on or always 50.
  • Putting aria-checked on the label span instead of the element that has the role.
  • Writing aria-checked="checked" or aria-valuenow="40%"; the values must be true or false, or a plain number.
  • Removing the role to silence the finding, which turns the switch into an unnamed button.
  • Building a switch, slider or spinbutton from divs when a native input would carry its own state.

WCAG criteria this rule maps to

axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:

The scanner knows which attributes each role requires and can see when one is absent. It cannot see whether the attribute is kept up to date when the control is used, so check that by hand. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.

Scan your own page for this and 63 other checks

Open any page in Chrome, click Websight, and get a score out of 100 with every issue explained and a draft fix snippet per element.

Add Websight to Chrome

Free scans, no account, nothing leaves your computer. Automated tools find only part of the problems; the extension says so on every report.