jsx-a11y/prefer-tag-over-role

Require the HTML element instead of a role that imitates it

Also called jsx_a11y/prefer-tag-over-role

A role only changes what a screen reader announces. The Tab key skips <div role="button">, and it doesn't react to Enter or Space until you add all of that by hand. <button> already does it, in every browser.

A role is reported if HTML has an element with that role and you used something else, including a component. The message names the elements to choose from. Roles without an HTML element, such as tab or alert, aren't reported. Only a role written as a string is checked.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"jsx-a11y/prefer-tag-over-role" = "error" # or "warn"

Examples#

example.jsx4 problems
const save = <div role="button" onClick={saveDraft}>Save</div>;
const menu = <div role="navigation" />;
const title = <span role="heading" aria-level={2}>Settings</span>;
const post = <Card role="article" />;
example.jsxNo problems
const save = <button onClick={saveDraft}>Save</button>;
const menu = <nav />;
const title = <h2>Settings</h2>;
const tab = <div role="tab" />;

When not to use it#

You can't build some widgets from the native element, for example a listbox with rich options that <select> can't show. If you build a lot of those, this rule reports each one.