You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|[template-no-aria-hidden-body](docs/rules/template-no-aria-hidden-body.md)| disallow aria-hidden on body element | 📋 | 🔧 ||
265
-
|[template-no-aria-unsupported-elements](docs/rules/template-no-aria-unsupported-elements.md)| disallow ARIA roles, states, and properties on elements that do not support them | 📋 |||
|[template-no-redundant-role](docs/rules/template-no-redundant-role.md)| disallow redundant role attributes | 📋 | 🔧 ||
280
-
|[template-no-unsupported-role-attributes](docs/rules/template-no-unsupported-role-attributes.md)| disallow ARIA attributes that are not supported by the element role | 📋 | 🔧 ||
281
-
|[template-no-whitespace-within-word](docs/rules/template-no-whitespace-within-word.md)| disallow excess whitespace within words (e.g. "W e l c o m e") | 📋 |||
282
-
|[template-require-aria-activedescendant-tabindex](docs/rules/template-require-aria-activedescendant-tabindex.md)| require non-interactive elements with aria-activedescendant to have tabindex | 📋 | 🔧 ||
283
-
|[template-require-context-role](docs/rules/template-require-context-role.md)| require ARIA roles to be used in appropriate context | 📋 |||
284
-
|[template-require-iframe-title](docs/rules/template-require-iframe-title.md)| require iframe elements to have a title attribute | 📋 |||
285
-
|[template-require-input-label](docs/rules/template-require-input-label.md)| require label for form input elements | 📋 |||
286
-
|[template-require-lang-attribute](docs/rules/template-require-lang-attribute.md)| require lang attribute on html element | 📋 |||
|[template-require-media-caption](docs/rules/template-require-media-caption.md)| require captions for audio and video elements | 📋 |||
289
-
|[template-require-presentational-children](docs/rules/template-require-presentational-children.md)| require presentational elements to only contain presentational children | 📋 |||
290
-
|[template-require-valid-alt-text](docs/rules/template-require-valid-alt-text.md)| require valid alt text for images and other elements | 📋 |||
291
-
|[template-require-valid-form-groups](docs/rules/template-require-valid-form-groups.md)| require grouped form controls to have fieldset/legend or WAI-ARIA group labeling ||||
292
-
|[template-table-groups](docs/rules/template-table-groups.md)| require table elements to use table grouping elements | 📋 |||
|[template-no-aria-hidden-body](docs/rules/template-no-aria-hidden-body.md)| disallow aria-hidden on body element | 📋 | 🔧 ||
265
+
|[template-no-aria-unsupported-elements](docs/rules/template-no-aria-unsupported-elements.md)| disallow ARIA roles, states, and properties on elements that do not support them | 📋 |||
|[template-no-redundant-role](docs/rules/template-no-redundant-role.md)| disallow redundant role attributes | 📋 | 🔧 ||
281
+
|[template-no-unsupported-role-attributes](docs/rules/template-no-unsupported-role-attributes.md)| disallow ARIA attributes that are not supported by the element role | 📋 | 🔧 ||
282
+
|[template-no-whitespace-within-word](docs/rules/template-no-whitespace-within-word.md)| disallow excess whitespace within words (e.g. "W e l c o m e") | 📋 |||
283
+
|[template-require-aria-activedescendant-tabindex](docs/rules/template-require-aria-activedescendant-tabindex.md)| require non-interactive elements with aria-activedescendant to have tabindex | 📋 | 🔧 ||
284
+
|[template-require-context-role](docs/rules/template-require-context-role.md)| require ARIA roles to be used in appropriate context | 📋 |||
285
+
|[template-require-iframe-title](docs/rules/template-require-iframe-title.md)| require iframe elements to have a title attribute | 📋 |||
286
+
|[template-require-input-label](docs/rules/template-require-input-label.md)| require label for form input elements | 📋 |||
287
+
|[template-require-lang-attribute](docs/rules/template-require-lang-attribute.md)| require lang attribute on html element | 📋 |||
|[template-require-media-caption](docs/rules/template-require-media-caption.md)| require captions for audio and video elements | 📋 |||
290
+
|[template-require-presentational-children](docs/rules/template-require-presentational-children.md)| require presentational elements to only contain presentational children | 📋 |||
291
+
|[template-require-valid-alt-text](docs/rules/template-require-valid-alt-text.md)| require valid alt text for images and other elements | 📋 |||
292
+
|[template-require-valid-form-groups](docs/rules/template-require-valid-form-groups.md)| require grouped form controls to have fieldset/legend or WAI-ARIA group labeling ||||
293
+
|[template-table-groups](docs/rules/template-table-groups.md)| require table elements to use table grouping elements | 📋 |||
Disallow native interactive elements from being assigned non-interactive ARIA roles.
6
+
7
+
Assigning a non-interactive role to a native interactive element (e.g. `<button role="heading">`) strips the element's built-in keyboard, focus, and activation semantics — leaving users with a broken widget. The [first rule of ARIA use](https://www.w3.org/TR/using-aria/#rule1) says don't use ARIA if native semantics already cover the job; this rule enforces the related corollary.
8
+
9
+
The interactive-element set is derived in layers, mirroring [jsx-a11y's `isInteractiveElement`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/util/isInteractiveElement.js): aria-query's `elementRoles` (with its attribute constraints, e.g. `<a href>`, `<input type="…">`, `<select multiple>`) is the primary signal; axobject-query's AX-tree mapping is consulted only as a fallback for tags that have no interactive `elementRoles` entry.
10
+
11
+
Two deviations for real-world false-positive patterns:
12
+
13
+
-`<canvas>` is **not** treated as inherently interactive. Its AXObject is widget-typed but aria-query assigns it no inherent role; authors legitimately set `role="img"` or `role="presentation"` on canvases.
14
+
-`<audio>` and `<video>` are only interactive when the `controls` attribute is present. Without it they render no user-operable UI (e.g. background / decorative media).
15
+
16
+
## Examples
17
+
18
+
This rule **forbids** the following:
19
+
20
+
```gjs
21
+
<template>
22
+
<button role="heading">Click</button>
23
+
<a href="/x" role="banner">Link</a>
24
+
<button role="presentation">Click</button>
25
+
</template>
26
+
```
27
+
28
+
This rule **allows** the following:
29
+
30
+
```gjs
31
+
<template>
32
+
<button role="menuitem">Item</button>
33
+
<button role="button">Click</button>
34
+
<a href="/x" role="link">Link</a>
35
+
<div role="heading" aria-level="1">Story</div>
36
+
</template>
37
+
```
38
+
39
+
## References
40
+
41
+
-[WAI-ARIA 1.2 — Role taxonomy](https://www.w3.org/TR/wai-aria-1.2/#roles_categorization)
0 commit comments