prefer-tag-over-role
Configuration
Rule Details
This rule enforces that an explicit ARIA
role is not used in
place of a semantic HTML element that already provides that role natively.
Native elements expose their semantics to assistive technology automatically
and come with built-in keyboard, focus, and form behavior — re-declaring the
role on a generic container loses those affordances and adds another way for
the implementation to diverge from the announced role.
The rule fires on a JSX opening element when all of the following hold:
- The element carries a
roleattribute whose value resolves to a non-empty string. - The LAST whitespace-separated token of that string is a non-abstract ARIA
role with one or more semantic HTML element mappings (
heading→<h1>…<h6>,checkbox→<input type="checkbox">,link→<a href=...>/<area href=...>, etc.). - The element's effective tag name (after resolving
settings['jsx-a11y'].polymorphicPropNameandsettings['jsx-a11y'].components) is NOT one of those semantic HTML elements.
Non-literal role values (Identifiers, CallExpressions, template literals
with substitutions, etc.) cannot be statically determined to a string and
never trigger the rule. The role attribute name is matched
case-insensitively, matching getProp's default. Multi-token role values
(role="button checkbox") are matched on the LAST token only —
role="button checkbox" is treated as role="checkbox" for the purpose of
this rule. Whitespace inside a role string is interpreted as the ASCII space
character U+0020; tabs and other Unicode whitespace are part of the token.
Examples of incorrect code for this rule:
Examples of correct code for this rule: