ARIA Rule

ARIA attributes must follow the conditions of the element's role aria-conditional-attr

A few ARIA attributes are allowed on a role only under conditions. The ones you will actually meet: aria-checked on a native input type=checkbox must agree with the checked state (and is best left off), and aria-level, aria-posinset and aria-setsize on a row only make sense inside a treegrid. Break the condition and the browser has two stories about the same control.

Websight reports this as ARIA attributes must be used as specified for the element's role

Who it affects

Someone using a screen reader hears a checkbox announced as checked while the box on screen is empty, ticks it to be sure, and has now unticked the thing they wanted.

Someone using a braille display reads a state code that disagrees with what the form will actually submit.

Someone navigating a data table by row hears level and position numbers that mean nothing because the table is not a tree.

Broken versus fixed

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

Broken

The box is empty on screen. Depending on the browser and screen reader, it is announced as checked, or as not checked, or flips between the two once it is clicked. The form will submit it as unticked.

Fixed

Announced: Remember me on this device, checkbox, not checked. The native input reports its own state and it always matches the screen.

Show the markup behind both examples
Broken
<style>body{font-family:system-ui;padding:16px;margin:0}label{display:flex;align-items:center;gap:8px}input{width:18px;height:18px}</style>
<label>
  <input type="checkbox" name="remember" aria-checked="true">
  Remember me on this device
</label>
Fixed
<style>body{font-family:system-ui;padding:16px;margin:0}label{display:flex;align-items:center;gap:8px}input{width:18px;height:18px}</style>
<label>
  <input type="checkbox" name="remember">
  Remember me on this device
</label>

Test it by hand in two minutes

  1. Search the page source for aria-checked. For each hit on an input type=checkbox or radio, remove it and see if anything breaks; it usually does not.
  2. Tick the box with the mouse and inspect it. If aria-checked still says the old value, the attribute is not being kept in sync.
  3. Turn on VoiceOver or NVDA, Tab to the checkbox and press Space. The state you hear should change each time and match the box on screen.
  4. For aria-level, aria-posinset or aria-setsize on a row, check the nearest ancestor role. If it is table or grid rather than treegrid, the attributes do nothing useful.

The fix

Before
<input type="checkbox" name="remember" aria-checked="true">
After
<input type="checkbox" name="remember" checked>

A native checkbox already tells assistive technology whether it is ticked. Use the checked attribute (or the checked property in script) and drop aria-checked altogether.

Tree attributes on a row in an ordinary grid

Before
<div role="grid">
  <div role="row" aria-level="2" aria-posinset="1" aria-setsize="4">...</div>
</div>
After
<div role="grid">
  <div role="row">...</div>
</div>

aria-level, aria-posinset and aria-setsize on a row are only meaningful inside role="treegrid". In a plain grid, remove them.

Rows that really do form a tree

Before
<div role="grid">
  <div role="row" aria-level="2">...</div>
</div>
After
<div role="treegrid">
  <div role="row" aria-level="2" aria-expanded="false">...</div>
</div>

If the rows genuinely nest and expand, the container should be a treegrid, and then the level attributes are correct.

Common mistakes

  • Keeping aria-checked on a native checkbox and trying to update it in script to match, which only works until someone forgets.
  • Setting aria-checked="false" on a box that has the checked attribute, hoping to show it as unticked.
  • Adding aria-level to table rows to indent them visually; use CSS for that.
  • Changing the input to a div with role="checkbox" so the attribute is allowed, which throws away the free keyboard support.

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 can see aria-checked on a native checkbox that disagrees with its checked state, and tree attributes on a row outside a treegrid. It cannot see state that goes wrong later in script, so test the control by hand after interacting with it. 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.