( Robust / WCAG 4.1.2 )
Required ARIA attribute is missing
What is this issue?
An element carries an ARIA role that the WAI-ARIA specification defines as requiring one or more specific state attributes, and at least one of those required attributes isn’t present on the element at all. Several common roles carry this requirement: checkbox and switch require aria-checked, combobox requires aria-expanded, and slider requires aria-valuenow, among others.
This is a different failure from an attribute with the wrong or missing value; here, the attribute itself is entirely absent from the element, not present with a bad value. A <div role="checkbox"> with no aria-checked attribute anywhere in its markup fails this check regardless of what the checkbox’s actual checked state is supposed to be.
Why does this matter?
A role like checkbox tells assistive technology what kind of control this is, but the role alone carries no information about the control’s current condition. That’s exactly what the required attribute is for: without aria-checked, a screen reader can announce “checkbox” but has nothing to say about whether it’s checked, unchecked, or in a mixed state.
For a settings toggle, a filter checkbox, or any control where the current state is the entire point of interacting with it, this isn’t a minor gap; it’s the removal of the one piece of information the control exists to convey. A user can activate the control repeatedly and never receive confirmation of what state they’ve left it in, turning every interaction into a guess.
Who is affected?
- Screen reader users: hear a role (“checkbox,” “switch”) with no accompanying state, so they can’t tell whether the control is currently on or off, expanded or collapsed, without some other, indirect confirmation.
- Cognitive disabilities: lose the state feedback that would otherwise confirm an action took effect, adding uncertainty about whether an interaction succeeded and increasing the mental effort needed to track it manually.
What users experience
Sofia uses NVDA on Windows to manage notification preferences in a web app’s settings page. Each preference is a custom toggle built as <div role="checkbox"> with a click handler that changes its visual appearance, but the required aria-checked attribute was never added to the markup. NVDA announces every toggle as “checkbox” with no checked or unchecked state, no matter how many times Sofia activates one. She ends up opening the browser’s zoom to 400% to visually confirm each toggle’s color before moving to the next, a workaround a sighted user at normal zoom never needs.
How do I fix it?
Add the required attribute with a value that accurately reflects the control’s current state, and update that value every time the control’s state changes. This works because the required attribute is exactly what a screen reader looks for to announce state alongside the role. Once it’s present and accurate, “checkbox, checked” or “checkbox, not checked” is announced automatically without any other markup changes needed.
Set the attribute’s initial value to match the control’s real starting state when the page first renders, not a placeholder that gets corrected later; a screen reader user who lands on the control before your script updates it will hear whatever value is there first. Wire the same event handler that changes the control’s visual appearance to also update its ARIA attribute, so the two can never drift out of sync.
Code Examples
<div role="checkbox" tabindex="0">Email notifications</div><!-- aria-checked is required by the checkbox role and reflects real state -->
<div role="checkbox" tabindex="0" aria-checked="false">Email notifications</div>Adding aria-checked="false" gives the checkbox role the state it’s required to carry, matching the control’s actual unchecked starting condition. The click handler that toggles the control’s visual appearance also needs to flip this attribute’s value between "true" and "false" on every activation; the markup fix here only covers the missing initial state; keeping it accurate afterward is a scripting responsibility, not a one-time attribute addition.
Common Mistakes
Mistake: “I’ll add the attribute once the user interacts with the control, since it starts in a default state anyway.” A screen reader user can land on the control and query its state before ever interacting with it, so “default state” still needs to be announced accurately from the very first render; there’s no grace period where a missing required attribute is acceptable.
Mistake: “The role already implies the default state, so I don’t need to spell it out.” No ARIA role has an implicit default value for its required state attributes: checkbox doesn’t imply “unchecked” any more than it implies “checked.” The specification requires the attribute to be explicitly present precisely because the role alone carries no state information.
Mistake: “My CSS class already shows which state the control is in, so the ARIA attribute is redundant.” A CSS class communicates state visually, to sighted users looking at the screen. Assistive technology reads the accessibility tree, not applied class names, so a visually-obvious checked state through styling alone is completely invisible to a screen reader unless the required ARIA attribute is also present and accurate.
How RedFlag Detects This
Automated: axe-core rule, runs on every scan. RedFlag calls axe-core’s aria-required-attr rule as part of every scan, restricted to the WCAG 2.0/2.1/2.2 A and AA rule set. The rule resolves each element’s role, explicit or implicit, then checks that every attribute the WAI-ARIA specification marks as required for that role is present on the element, flagging any that are missing.
False negative: the rule confirms a required attribute exists; it can’t confirm its value stays accurate as the control’s real state changes; a checkbox with aria-checked="false" hardcoded and never updated by its click handler still passes this specific check even though the announced state becomes wrong the moment a user actually checks it. False positive: none typical for this check, since confirming an attribute’s presence against a fixed per-role requirement list is a binary condition axe-core evaluates reliably. Manual step: activate every flagged-and-fixed control and confirm the required attribute’s value actually updates to match, not just that it’s present at page load.
Manual Testing
- Open the page in Chrome or Firefox with NVDA or VoiceOver running.
- Tab to each custom control (toggle, checkbox, combobox, slider) built from a
<div>or<span>rather than a native form element. - Listen for a state announcement immediately after the role and name: “checkbox, checked” or “checkbox, not checked,” not just “checkbox” alone with no state.
- Activate the control and listen again. The announced state should flip to match the new visual state every time.
- Open the browser’s accessibility inspector (Chrome DevTools → Elements → Accessibility pane) and confirm the computed properties list includes the required state attribute for that role.
Related WCAG Success Criteria
4.1.2 Name, Role, Value: Every interface component must expose its current state to assistive technology. A missing required attribute fails this criterion directly on the “value” requirement, since the role is announced but the state that role is defined to carry is entirely absent.
Related Issues
ARIA attribute is not allowed for this role is the mirror-image failure: an attribute present on a role that doesn’t support it, instead of a required attribute missing from a role that needs it.
ARIA role is invalid is a prerequisite check this rule assumes is already correct; a genuinely invalid role has no meaningful “required attributes” to check in the first place.
ARIA attribute is not valid for the current role value covers a related but distinct case: an attribute that’s valid only under a specific condition, rather than unconditionally required by the role itself.
ARIA attribute has an invalid value is the natural next check once a required attribute is present; it verifies the value inside that attribute is actually one the specification allows, not just that the attribute exists.
Element uses a deprecated ARIA role commonly appears in the same legacy custom-control component as a missing required attribute, since both stem from ARIA added without checking the role’s current specification.
Element role is missing required child elements is the structural equivalent of this rule: a role requiring specific children instead of specific attributes, both flagging an incomplete implementation of the role’s contract.
References
- W3C Understanding 4.1.2: Name, Role, Value
- WAI-ARIA 1.2: Definition of Roles
- MDN: ARIA states and properties
- ARIA Authoring Practices: Checkbox Pattern
Frequently asked questions
Which ARIA roles have required attributes?
Several common roles do: checkbox and switch require aria-checked, combobox requires aria-expanded, slider requires aria-valuenow, and scrollbar requires aria-controls and aria-valuenow, among others. Each role's required-attribute list is fixed by the WAI-ARIA specification, not something a developer chooses.
Does using the native HTML equivalent avoid this problem entirely?
Yes, in most cases. A native input type="checkbox" already exposes checked state to assistive technology through the browser's built-in accessibility mapping, with no ARIA attribute required at all. This rule mainly affects custom, div-or-span-based controls standing in for a native element.
What value should a required attribute have when the control first loads?
Whatever accurately reflects the control's actual initial state, never a placeholder or guess. A checkbox that starts unchecked needs aria-checked="false" from the first render, not aria-checked="true" swapped in later, since a screen reader user hearing the wrong initial state has no way to know it was inaccurate.
Is a missing required attribute worse than an incorrect value in that attribute?
They cause different failures. A missing attribute means no state is announced at all, so the user gets no information. An incorrect value means a specific, wrong piece of information is announced confidently, which can be more misleading since the user has no reason to doubt it.
Can JavaScript update a required attribute after the page loads, or does it need to be in the initial HTML?
JavaScript updating it dynamically is fine and expected for interactive controls, as long as the update happens in the same operation that changes the control's visible state. The requirement is that the attribute exists and stays accurate, not that it be hardcoded in the initial markup.