Skip to main content
HTML Validation

An “li” element that is a descendant of a “role=menu” element or “role=menubar” element must not have any “role” value other than “group”, “menuitem”, “menuitemcheckbox”, “menuitemradio”, or “separator”.

About This HTML Issue

An <li> inside an element with role="menu" or role="menubar" has a role that doesn't belong in a menu.

These two roles describe an application menu, like the one at the top of a desktop program. Screen readers expect every item in it to be a menuitem, menuitemcheckbox or menuitemradio, sometimes grouped with group or split with separator. An <li> set to listitem, option, link, button or tab breaks that structure. The check covers every <li> under the menu, not only its direct children, so a nested list such as a language picker built as a listbox triggers it too.

An <li> with no role attribute passes, and so does one with role="none" or role="presentation". Only an explicit role outside the allowed list raises the error.

Usually the menu roles shouldn't be there at all. They tend to end up on a site's main navigation, which is just a list of links to other pages. A screen reader that announces a "menu bar" tells the user to move between items with the arrow keys, and few sites script that behavior. Remove role="menu", role="menubar" and the item roles, and keep a <nav> with a plain list of links. Save the menu roles for widgets that work like a desktop menu, where each item runs a command. There, each <li> is either a menu item itself or has role="none" and wraps one.

Invalid example

A language picker built as a listbox sits inside navigation marked up as a menubar. Each <li role="option"> triggers the error:

<nav aria-label="Main">
  <ul role="menubar">
    <li role="none"><a role="menuitem" href="/">Home</a></li>
    <li role="none"><a role="menuitem" href="/news/">News</a></li>
    <li role="none">
      <ul role="listbox" aria-label="Language">
        <li role="option" aria-selected="true">English</li>
        <li role="option" aria-selected="false">Español</li>
      </ul>
    </li>
  </ul>
</nav>

Valid example

Site navigation as plain lists of links, with no menu roles:

<nav aria-label="Main">
  <ul>
    <li><a href="/" aria-current="page">Home</a></li>
    <li><a href="/news/">News</a></li>
  </ul>
  <ul aria-label="Language">
    <li><a href="/" aria-current="true">English</a></li>
    <li><a href="/es/" hreflang="es" lang="es">Español</a></li>
  </ul>
</nav>

For a real application menu, every <li> gets a menu role or role="none". The items also need scripted keyboard support (arrow keys, Escape, focus handling), as the WAI-ARIA menubar pattern describes:

<ul role="menubar" aria-label="Editor">
  <li role="none">
    <button type="button" role="menuitem" aria-haspopup="menu" aria-expanded="true">Format</button>
    <ul role="menu" aria-label="Format">
      <li role="menuitemcheckbox" aria-checked="true" tabindex="-1">Bold</li>
      <li role="menuitemcheckbox" aria-checked="false" tabindex="-1">Italic</li>
      <li role="separator"></li>
      <li role="menuitem" tabindex="-1">Clear formatting</li>
    </ul>
  </li>
</ul>

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?
🌍 Trusted by teams worldwide

Validate at scale.
Ship accessible websites, faster.

Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.

Scheduled Reports
API Access
Open Source Standards
€5 / week

1K Weekly

1,000 monthly checks. Cancel anytime.

Get 1K Weekly →

Join teams across 40+ countries