Skip to main content
HTML Validation

Bad value “button” for attribute “role” on element “li”.

About This HTML Issue

The <li> element has an implicit ARIA role of listitem, and the WHATWG HTML specification restricts which roles can be applied to it. The button role is not among the roles permitted on <li>. When you set role="button" on a <li>, you’re telling assistive technologies that the element is a button, but the browser and the spec still recognize it as a list item. This creates a semantic conflict that can confuse screen readers and other assistive tools, leading to a degraded experience for users who rely on them.

Beyond the validation error, there are practical accessibility concerns. A real <button> element comes with built-in keyboard support (it’s focusable and activatable with Enter or Space), whereas a <li> with role="button" lacks these behaviors by default. You would need to manually add tabindex, keyboard event handlers, and focus styling—effectively recreating what <button> gives you for free. This is error-prone and violates the ARIA principle of preferring native HTML elements over ARIA role overrides.

How to Fix

There are several approaches depending on your use case:

  1. Place a <button> inside each <li> — This is the best approach when you have a list of actions, as it preserves list semantics while providing proper button functionality.
  2. Use <button> elements directly — If the items aren’t truly a list, drop the <ul>/<li> structure and use <button> elements instead.
  3. Use a <div> or <span> with role="button" — If you cannot use a native <button> for some reason, these elements accept the button role. You’ll also need to add tabindex="0" and keyboard event handling yourself.

Examples

❌ Invalid: role="button" on <li> elements

<ul>
  <li role="button">Copy</li>
  <li role="button">Paste</li>
  <li role="button">Delete</li>
</ul>

This triggers the validation error because <li> does not permit the button role.

✅ Fixed: Using <button> elements inside <li>

<ul>
  <li><button type="button">Copy</button></li>
  <li><button type="button">Paste</button></li>
  <li><button type="button">Delete</button></li>
</ul>

This preserves the list structure while providing proper, accessible button behavior with no extra work.

✅ Fixed: Using standalone <button> elements

If the list structure isn’t meaningful, remove it entirely:

<div>
  <button type="button">Copy</button>
  <button type="button">Paste</button>
  <button type="button">Delete</button>
</div>

✅ Fixed: Using a toolbar pattern

For a group of related actions, the ARIA toolbar pattern is a great fit:

<div role="toolbar" aria-label="Text actions">
  <button type="button">Copy</button>
  <button type="button">Paste</button>
  <button type="button">Delete</button>
</div>

✅ Fixed: Using role="button" on a permitted element

If you truly cannot use a native <button>, a <div> or <span> can accept the button role. Note that you must manually handle focus and keyboard interaction:

<div role="button" tabindex="0">Copy</div>

However, this approach is almost always inferior to using a native <button> and should only be used as a last resort. Native elements provide keyboard behavior, form integration, and consistent styling hooks that are difficult to replicate reliably.

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?

Ready to validate your sites?
Start your free trial today.