# An element with “role=tab” must be contained in, or owned by, an element with the “role” value “tablist”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/an-element-with-role-tab-must-be-contained-in-or-owned-by-an-element-with-the-role-value-tablist
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

An element with `role="tab"` must sit inside an element with `role="tablist"`, or be claimed by one through the `aria-owns` attribute. When a tab lives outside a tablist, screen readers can't tell how many tabs are in the group or which one is selected, so the whole tab interface breaks for people who rely on assistive technology. To fix it, place your `role="tab"` elements inside a `role="tablist"` container.

The `tab` role only carries meaning inside a `tablist`. A tab controls the visibility of a matching `role="tabpanel"`, and the `tablist` groups the tabs together so assistive technologies can announce position (for example, "tab 2 of 4") and move focus between tabs with the arrow keys. Take the tab out of its `tablist` and that grouping disappears, leaving the screen reader with a button it can't place in any structure.

The W3C validator emits this message in two slightly different wordings depending on its version: `an element with the “role” value “tablist”` and `an element with “role=tablist”`. Both report the same problem, and the fix is identical.

There are two ways to establish the required relationship. Nesting the tabs directly inside the `tablist` is the common one. When your layout or framework makes that nesting impossible, point `aria-owns` from the `tablist` at the tab `id`s instead.

## Invalid example

Here the `role="tab"` buttons are siblings of the `tablist` rather than children of it, so no `tablist` contains or owns them.

```html
<div class="tabs">
  <div role="tablist" aria-label="Account settings"></div>
  <button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">
    Profile
  </button>
  <button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">
    Billing
  </button>
</div>
```

## Valid example

Moving the tabs inside the `role="tablist"` element gives them the parent they need.

```html
<div class="tabs">
  <div role="tablist" aria-label="Account settings">
    <button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1" tabindex="0">
      Profile
    </button>
    <button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2" tabindex="-1">
      Billing
    </button>
  </div>
  <div id="panel-1" role="tabpanel" aria-labelledby="tab-1">
    <p>Profile settings</p>
  </div>
  <div id="panel-2" role="tabpanel" aria-labelledby="tab-2" hidden>
    <p>Billing settings</p>
  </div>
</div>
```

If you genuinely can't nest the tabs in the DOM, keep them where they are and add `aria-owns="tab-1 tab-2"` to the `role="tablist"` element so assistive technologies still treat the list as the owner of those tabs.
