# Element X is missing one or more of the following attributes: “role”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/element-x-is-missing-one-or-more-of-the-following-attributes-role
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

ARIA (Accessible Rich Internet Applications) works as a system where **roles** define what an element *is*, and **states and properties** describe the element's current condition or characteristics. Certain ARIA attributes are only valid when used on elements that have a specific role — either explicitly declared via the `role` attribute or implicitly provided by the HTML element itself. When you add an ARIA state or property to a generic element like a `<div>` or `<span>` without specifying a role, assistive technologies have no context for interpreting that attribute. For example, `aria-expanded="true"` on a plain `<div>` tells a screen reader that something is expanded, but it doesn't communicate *what* is expanded — is it a button, a navigation menu, a tree item? The role provides that crucial context.

This matters for several reasons:

- **Accessibility**: Screen readers and other assistive technologies rely on the combination of roles and their associated states/properties to convey meaningful information to users. An ARIA property without a role is ambiguous and can lead to a confusing experience.
- **Standards compliance**: The [WAI-ARIA specification](https://www.w3.org/TR/wai-aria/) defines which states and properties are allowed on which roles. Using an ARIA attribute outside of a valid role context violates the spec.
- **Predictable behavior**: Browsers and assistive technologies may handle orphaned ARIA attributes inconsistently, leading to unpredictable results across different platforms.

To fix this issue, you have two approaches:

1. **Add an explicit `role` attribute** to the element, choosing a role that supports the ARIA attributes you're using.
2. **Use a semantic HTML element** that already has an implicit ARIA role. For instance, `<nav>` has an implicit role of `navigation`, `<button>` has an implicit role of `button`, and `<header>` has an implicit role of `banner`. This is generally the preferred approach, as it provides built-in keyboard interaction and semantics without extra effort.

When choosing a role, make sure the ARIA states and properties you're using are actually supported by that role. For example, `aria-expanded` is supported by roles like `button`, `combobox`, `link`, `treeitem`, and others — but not by every role. Consult the [WAI-ARIA roles documentation](https://www.w3.org/TR/wai-aria/#role_definitions) to verify compatibility.

## Examples

### Invalid: ARIA property without a role

This `<div>` uses `aria-expanded` but has no role, so the validator doesn't know what kind of element this is supposed to be.

```html
<div aria-expanded="true">
  Menu contents
</div>
```

### Fixed: Adding an explicit role

Adding `role="button"` tells assistive technologies that this is a button that can be expanded or collapsed.

```html
<div role="button" aria-expanded="true" tabindex="0">
  Menu contents
</div>
```

### Fixed: Using a semantic HTML element instead

A `<button>` element already has an implicit `button` role, so no explicit `role` attribute is needed. This is the preferred approach.

```html
<button aria-expanded="true">
  Toggle menu
</button>
```

### Invalid: `aria-label` on a generic element

A `<span>` has no implicit role, so `aria-label` has no meaningful context here.

```html
<span aria-label="Close dialog">X</span>
```

### Fixed: Using a semantic element or adding a role

```html
<button aria-label="Close dialog">X</button>
```

Or, if you need to use a `<span>`:

```html
<span role="button" tabindex="0" aria-label="Close dialog">X</span>
```

### Using elements with implicit roles

Many HTML elements already carry implicit ARIA roles, so adding ARIA states and properties to them is valid without an explicit `role` attribute:

```html
<!-- <nav> has implicit role="navigation" -->
<nav aria-label="Main navigation">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/about">About</a></li>
  </ul>
</nav>

<!-- <details> supports aria-expanded implicitly -->
<details aria-describedby="help-text">
  <summary>More information</summary>
  <p id="help-text">Additional details about this topic.</p>
</details>
```

As a general rule, always prefer native semantic HTML elements over generic elements with ARIA roles. Native elements come with built-in keyboard support, focus management, and accessibility semantics — reducing the amount of custom code you need to write and maintain.
