# Certain ARIA roles must be contained within specific parent roles.

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

Certain ARIA roles are defined as items that must appear inside a specific parent role in the accessibility tree. For example, an element with `role="listitem"` must be a child of an element with `role="list"`, and an element with `role="tab"` must be a child of an element with `role="tablist"`. When these parent-child relationships are missing, assistive technologies cannot determine the structural context of the element, and the information they convey to users becomes incomplete or wrong.

Screen reader users are the most affected. Screen readers rely on the accessibility tree to communicate structure. A tab that exists outside a tablist, or a row that exists outside a table or grid, loses its semantic meaning. A screen reader might announce the element's role without any surrounding context, or skip it entirely. Users then have no way to understand how the element relates to the rest of the page.

This rule maps to WCAG 2.0+ Success Criterion 1.3.1 "Info and Relationships" (Level A), which requires that information, structure, and relationships conveyed through presentation are programmatically determinable. When a required parent role is missing, the structural relationship between the child and its container is not programmatically determinable.

## How the accessibility tree works here

The required parent-child relationship is evaluated in the accessibility tree, not the DOM tree. This distinction matters. Some intermediate DOM elements may have `role="presentation"` or `role="none"`, which removes them from the accessibility tree. In that case, the accessibility tree "looks through" those elements. An element with `role="listitem"` inside a `<div role="presentation">` inside a `<ul role="list">` still has the correct parent in the accessibility tree.

The `aria-owns` attribute can also rearrange parent-child relationships in the accessibility tree, making an element a child of another element regardless of DOM position. However, support for `aria-owns` varies across browsers and assistive technologies, so native DOM nesting is more reliable.

## Common roles and their required parents

Here are some of the most frequently encountered required context roles from WAI-ARIA 1.2:

- `listitem` requires `list`
- `tab` requires `tablist`
- `row` requires `table`, `grid`, `rowgroup`, or `treegrid`
- `cell` requires `row`
- `gridcell` requires `row`
- `columnheader` requires `row`
- `rowheader` requires `row`
- `option` requires `listbox` or `group`
- `menuitem` requires `menu`, `menubar`, or `group`
- `treeitem` requires `tree` or `group`

## How to fix it

There are two approaches:

1. Wrap the element in a parent that has the required context role. If you have an element with `role="listitem"`, make sure its parent (in the accessibility tree) has `role="list"`.

2. Use native HTML elements that provide the correct structure automatically. A `<li>` inside a `<ul>` already has the right implicit roles without any ARIA attributes. Native HTML is generally preferred because it has broader support and requires less manual work.

When the fix depends on restructuring the component's markup, the appropriate solution will vary by context.

## Examples

### Incorrect: listitem without a list parent

```html
<div>
  <div role="listitem">Apples</div>
  <div role="listitem">Oranges</div>
</div>
```

The parent `<div>` has no role, so the `listitem` elements have no `list` context. A screen reader cannot tell the user that these items belong to a list or how many items the list contains.

### Correct: listitem inside a list parent

```html
<div role="list">
  <div role="listitem">Apples</div>
  <div role="listitem">Oranges</div>
</div>
```

### Correct: using native HTML instead

```html
<ul>
  <li>Apples</li>
  <li>Oranges</li>
</ul>
```

Native HTML is the simplest fix here. The `<ul>` implicitly has the `list` role, and each `<li>` implicitly has the `listitem` role.

### Incorrect: tab without a tablist parent

```html
<div>
  <button role="tab" aria-selected="true">Details</button>
  <button role="tab" aria-selected="false">Reviews</button>
</div>
```

The `tab` role requires a parent with `role="tablist"`. Without it, screen readers cannot present these elements as navigable tabs.

### Correct: tabs inside a tablist

```html
<div role="tablist">
  <button role="tab" aria-selected="true">Details</button>
  <button role="tab" aria-selected="false">Reviews</button>
</div>
```

### Incorrect: cells without a row parent

```html
<div role="table">
  <div role="cell">Name</div>
  <div role="cell">Email</div>
</div>
```

Each `cell` must be a direct child of a `row` in the accessibility tree.

### Correct: cells inside rows inside a table

```html
<div role="table" aria-label="Contacts">
  <div role="row">
    <div role="cell">Name</div>
    <div role="cell">Email</div>
  </div>
</div>
```

### Correct: presentation elements between parent and child in the DOM

```html
<div role="list">
  <div role="presentation">
    <div role="listitem">Apples</div>
    <div role="listitem">Oranges</div>
  </div>
</div>
```

The intermediate `<div>` has `role="presentation"`, which removes it from the accessibility tree. The `listitem` elements are still direct children of the `list` in the accessibility tree, so the required context is satisfied.
