ARIA Role Instead of a Native Element
Adding role="button" to a <div> tells assistive technology what the element pretends to be, and nothing else. The browser gives a real <button> keyboard focus, Enter and Space activation, a disabled state, and form submission. A div with a role gets none of that: you have to reimplement every piece, and most codebases stop after the role.
How common is this error?
We ran this validator over the home page of the Tranco top 5,000 websites in August 2026. 1,284 of the 2,655 sites we could reach hit it. That makes it the 4th most common HTML problem we found, across 12,463 occurrences. See the full study.
Most frequent wording: Prefer to use the native <button> element
Why It Matters
This is the most frequent finding with no guide in our sample, on 42% of sites. The result is a control that a mouse user can operate and a keyboard user cannot: it never receives focus, and pressing Enter does nothing. That fails WCAG 2.1.1 (Keyboard) at Level A, and it is invisible in testing unless someone puts the mouse down.
Common Causes
- Avoiding <button> because of its default browser styling, then adding the role to compensate.
- A card or row made clickable by attaching a handler to its container div.
- Component libraries that render a div and expose a `role` prop, leaving keyboard support to the consumer.
- Adding a role after an accessibility audit flagged the element, which satisfies the automated check without fixing the behaviour.
Code Examples
<!-- Mouse-only. No focus, no Enter, no Space, no disabled state --> <div role="button" onclick="save()">Save</div> <div role="navigation">...</div> <span role="heading" aria-level="2">Section title</span>
<button type="button" onclick="save()">Save</button> <nav>...</nav> <h2>Section title</h2>
How to Fix
- 1Replace the element with the native one: <button>, <nav>, <h2>, <ul>, <table>. The role then comes for free and cannot drift from the behaviour.
- 2If the element must stay a div (a legacy design system, a wrapper you do not control), you owe it tabindex="0", a keydown handler for both Enter and Space, and aria-disabled handling.
- 3Reset the browser styles rather than avoid the element. `all: unset` or a small reset class turns a <button> into a blank canvas without giving up its behaviour.
- 4Inside a form, remember that only a real <button> or <input> can submit. A div never will, whatever role you give it.
Frequently Asked Questions
Is role="button" on a div actually broken?
How do I remove a button's default styling?
What about a whole card that should be clickable?
Check Your HTML Now
Our validator detects this error automatically and shows the exact line number.
Open HTML ValidatorRelated HTML Errors
Button Missing the type Attribute
A <button> with no type defaults to submit and reloads the page from inside a form. Learn why the default bites, and when to use button, submit or reset.
Redundant ARIA Role
role="link" on an <a> and role="navigation" on a <nav> repeat what the element already means. Learn when to delete them, and the one case where role="list" earns its place.
Incorrect Tag Nesting
Incorrect HTML nesting makes browsers silently rewrite your DOM. Learn the nesting rules and fix p inside p, div inside span, and other broken structures.