# jsx-a11y/prefer-tag-over-role

> Require the HTML element instead of a `role` that imitates it

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.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

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

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 4} */}
```jsx
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" />;
```

Not reported:

{/* good */}
```jsx
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.
