# An element with the attribute “role=X” should not appear as a descendant of an element with the attribute “role=Y”.

> Canonical HTML version: https://rocketvalidator.com/html-validation/an-element-with-the-attribute-role-x-should-not-appear-as-a-descendant-of-an-element-with-the-attribute-role-y
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

An element with an interactive ARIA role, such as `menuitem` or `button`, is nested inside another element whose role already describes a single control, like a menu item inside a menu item.

ARIA in HTML treats an element with one of these outer roles like a native `<button>`: it can hold phrasing content, but no interactive descendants. Most of them also have presentational children in WAI-ARIA, so browsers don't expose their descendants to assistive technologies as separate elements. A screen reader announces the outer menu item and reads anything nested inside it as plain text. The arrow-key navigation of a menu can't reach a nested item either.

The validator checks descendants at any depth inside elements with `role` set to `button`, `checkbox`, `img`, `link`, `math`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `progressbar`, `radio`, `separator`, `slider`, `switch` or `tab`. It flags descendants whose role is `button`, `checkbox`, `combobox`, `grid`, `gridcell`, `listbox`, `menu`, `menubar`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `radio`, `scrollbar`, `searchbox`, `slider`, `spinbutton`, `switch`, `tab`, `textbox` or `treeitem`.

Nested submenus are the most common cause. A site menu gives each `<li>` `role="menuitem"` and puts the submenu, a `<ul role="menu">` with its own menu items, inside that `<li>`. Each submenu then gets one warning for the `role="menu"` list and one for every item in it. If the `<li>` elements also hold links, those links get their own warnings, starting with "The element "a" should not appear as a descendant of an element with the attribute "role=menuitem"." The same fix clears all of them.

In the WAI-ARIA menu pattern, a submenu sits next to the item that opens it, not inside it. Give each `<li>` `role="none"`, put `role="menuitem"` on the link or button inside it, and place the submenu `<ul role="menu">` after that element in the same `<li>`. Add `aria-haspopup="true"` and `aria-expanded` to the parent item so screen readers know it opens a submenu.

If the list is ordinary site navigation, remove `role="menubar"`, `role="menu"` and `role="menuitem"` altogether. The menu roles are meant for application menus like the ones in desktop software, and they need scripts that move focus with the arrow keys. A `<nav>` with nested lists of links and a `<button aria-expanded>` for each submenu needs no ARIA roles.

Other role combinations have the same fix: keep one interactive role per control. Move the role onto the element that performs the action, or move the inner control out of the outer one.

## Invalid example

```html
<ul role="menubar" aria-label="Main">
  <li role="menuitem" aria-haspopup="true" aria-expanded="false">
    Services
    <ul role="menu" aria-label="Services">
      <li role="menuitem">Consulting</li>
      <li role="menuitem">Training</li>
    </ul>
  </li>
</ul>
```

## Valid example

```html
<ul role="menubar" aria-label="Main">
  <li role="none">
    <button type="button" role="menuitem" aria-haspopup="true" aria-expanded="false">Services</button>
    <ul role="menu" aria-label="Services">
      <li role="menuitem">Consulting</li>
      <li role="menuitem">Training</li>
    </ul>
  </li>
</ul>
```

## Valid example for site navigation

```html
<nav aria-label="Main">
  <ul>
    <li>
      <button type="button" aria-expanded="false" aria-controls="services-menu">Services</button>
      <ul id="services-menu" hidden>
        <li><a href="/consulting">Consulting</a></li>
        <li><a href="/training">Training</a></li>
      </ul>
    </li>
  </ul>
</nav>
```
