# Elements must only use permitted ARIA attributes

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

The WAI-ARIA specification defines which attributes are permitted, required, or prohibited for each role. When you use a prohibited attribute on a role, you're relying on a combination that assistive technologies are not designed to support. The result is that the information you intended to communicate — such as a label or description — may be silently dropped.

This creates a serious problem for users who depend on assistive technologies, including people who are blind, deafblind, or have mobility impairments. Screen readers might ignore the prohibited attribute, leaving the user without context. Some assistive technologies may attempt to compensate, leading to inconsistent or confusing behavior across different tools and browsers.

A common example is using `aria-label` on an element with `role="presentation"` or `role="none"`. These roles explicitly tell assistive technologies to ignore the element's semantics, so labeling it with `aria-label` is contradictory. Similarly, text-level semantic roles like `code`, `insertion`, `deletion`, `strong`, `emphasis`, `subscript`, `superscript`, and `paragraph` prohibit `aria-label` and `aria-labelledby` because these roles represent inline text content that should not carry an accessible name separate from their text content.

## Related WCAG success criteria

This rule relates to **WCAG Success Criterion 4.1.2: Name, Role, Value (Level A)**, which requires that for all user interface components, the name, role, and states/properties can be programmatically determined. Using prohibited ARIA attributes violates this criterion because the intended name or state information cannot be reliably communicated to assistive technologies.

## How to fix it

When axe flags a prohibited ARIA attribute, consider these approaches:

1. **Remove the prohibited attribute** — If the information it conveys is not essential, simply remove it.
2. **Change the element's role** — Switch to a role that permits the attribute you need. For instance, if you need `aria-label`, don't use `role="none"`.
3. **Provide the information as visible text** — Instead of relying on the prohibited attribute, include the information directly in the page content where all users can access it.
4. **Move the attribute to a different element** — Place the attribute on a parent or child element that has a role supporting it.

## Examples

### Incorrect: `aria-label` on an element with `role="presentation"`

The `presentation` role tells assistive technologies to ignore the element. Adding `aria-label` contradicts this and will be ignored.

```html
<div role="presentation" aria-label="Navigation section">
  <a href="/home">Home</a>
  <a href="/about">About</a>
</div>
```

### Correct: Use a role that supports `aria-label`

If the element needs an accessible name, use a role that permits labeling, such as `navigation`.

```html
<nav aria-label="Navigation section">
  <a href="/home">Home</a>
  <a href="/about">About</a>
</nav>
```

### Incorrect: `aria-label` on a text-level semantic role

Roles like `code`, `strong`, `emphasis`, `insertion`, and `deletion` prohibit `aria-label` and `aria-labelledby`.

```html
<span role="code" aria-label="JavaScript variable declaration">
  const x = 10;
</span>
```

### Correct: Use visible text instead

Provide context through surrounding text content rather than a prohibited attribute.

```html
<p>
  The following JavaScript variable declaration
  <code>const x = 10;</code>
  assigns the value 10 to x.
</p>
```

### Incorrect: `aria-labelledby` on `role="none"`

```html
<h2 id="section-title">Features</h2>
<table role="none" aria-labelledby="section-title">
  <tr>
    <td>Fast</td>
    <td>Reliable</td>
  </tr>
</table>
```

### Correct: Remove the conflicting role or the prohibited attribute

If the table needs to be labeled, remove `role="none"` so it retains its native table semantics.

```html
<h2 id="section-title">Features</h2>
<table aria-labelledby="section-title">
  <tr>
    <td>Fast</td>
    <td>Reliable</td>
  </tr>
</table>
```

If the table is truly presentational and doesn't need a label, remove the `aria-labelledby` attribute instead.

```html
<table role="none">
  <tr>
    <td>Fast</td>
    <td>Reliable</td>
  </tr>
</table>
```
