# ARIA attributes must be allowed for the element's role.

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/accesslint/0.16/aria/aria-allowed-attr
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

Every WAI-ARIA role has a defined set of states and properties that it supports. When an ARIA attribute is used on an element whose role does not allow it, browsers and assistive technologies ignore that attribute. This means information a developer intended to convey may silently disappear from the accessibility tree, leaving screen reader users and other assistive technology users without the context they need.

For example, `aria-checked` is a supported property for the `checkbox` role but not for the `heading` role. Placing `aria-checked` on a heading element has no effect — assistive technologies will not announce a checked state because that attribute is meaningless in the context of a heading. The result is confusing markup that may mislead developers into thinking they have exposed state information when they have not.

This rule relates to WCAG 2.1 Success Criterion 4.1.2 (Name, Role, Value) at Level A. That criterion requires that user interface components expose their name, role, and current state to assistive technologies through standard mechanisms. Using an ARIA attribute that the element's role does not support breaks this contract because the attribute is silently dropped, and any state or property it was meant to communicate is lost.

## How ARIA attribute allowance works

ARIA attributes fall into two categories:

- **Global states and properties** (such as `aria-label`, `aria-describedby`, `aria-hidden`, and `aria-live`) are allowed on any element, regardless of role.
- **Non-global states and properties** (such as `aria-checked`, `aria-expanded`, `aria-selected`, and `aria-level`) are only valid on elements whose role lists them as inherited, supported, or required.

The WAI-ARIA specification defines exactly which attributes belong to each role. Some HTML elements also have special rules defined in the "ARIA in HTML" specification. For instance, the `audio` element has no implicit ARIA role, but it can accept attributes associated with the `application` role.

When a non-global ARIA attribute appears on an element whose role does not support it, the attribute is invalid. Browsers may ignore it entirely, so any assistive technology relying on it will not receive the intended information.

## How to fix it

1. Identify the element's role. If the element has an explicit `role` attribute, that is the role. Otherwise, use the element's implicit role (for example, `<button>` has an implicit role of `button`).
2. Check the WAI-ARIA specification for that role's supported, required, and inherited states and properties.
3. If the ARIA attribute is not allowed for the role, either remove the attribute or change the element's role to one that supports it.
4. If the attribute is needed for functionality, reconsider the component's structure. The element may need a different role, or the attribute may belong on a different element within the component.

## Examples

### Incorrect: `aria-checked` on a heading

The `heading` role does not support `aria-checked`. The attribute will be ignored.

```html
<h2 aria-checked="true">Settings</h2>
```

### Correct: remove the unsupported attribute

If the heading does not need a checked state, remove the attribute.

```html
<h2>Settings</h2>
```

### Incorrect: `aria-expanded` on a `row` role element

The `row` role does not list `aria-expanded` as a supported property in all contexts. This can cause the expanded state to be dropped.

```html
<div role="row" aria-expanded="true">
  <span role="cell">Item</span>
</div>
```

### Correct: use a role that supports `aria-expanded`

If the element needs to communicate an expanded/collapsed state, use a role that supports `aria-expanded`, such as `button`.

```html
<button aria-expanded="true" aria-controls="details-panel">
  Item
</button>
<div id="details-panel">
  <p>Details about the item.</p>
</div>
```

### Incorrect: `aria-selected` on a `button`

The `button` role does not support `aria-selected`. This attribute will have no effect.

```html
<button aria-selected="true">Option A</button>
```

### Correct: use `aria-pressed` instead

If the intent is to indicate a toggle state, `aria-pressed` is the appropriate attribute for a button.

```html
<button aria-pressed="true">Option A</button>
```

### Correct: global properties are always allowed

Global ARIA properties like `aria-label` and `aria-describedby` are valid on any element, so these do not trigger the rule.

```html
<h2 aria-label="Application settings">Settings</h2>
```
