no-noninteractive-element-interactions
Configuration
Rule Details
Non-interactive HTML elements and non-interactive ARIA roles indicate
content and containers in the user interface. A non-interactive element
does not support event handlers (mouse and key handlers). Non-interactive
elements include <main>, <area>, <h1> (and <h2> …), <p>, <img>,
<li>, <ul> and <ol>. Non-interactive WAI-ARIA roles include article,
banner, complementary, img, listitem, main, region and tooltip.
When this rule fires, move the event handler to a semantically interactive
element (<button>, <a href> …) or to an inner element with
role="presentation".
The rule fires on a JSX opening element when all of the following hold:
- The resolved element name is in the HTML DOM set (custom React components are skipped — the rule does not know what low-level element they render).
- After the per-element allow-list filter (see Rule Options below), the
element declares at least one of the configured
handlerswhose value resolves to a non-nullish expression (prop={null}/prop={undefined}do not count). - The element does not have
contentEditable="true"(compared against the raw attribute source, socontentEditable={true}andcontentEditable={"true"}do NOT exempt). - The element is not hidden from screen readers (no
aria-hidden={true}/aria-hidden="true", not an<input type="hidden">). - The
roleattribute, when statically a literal string, is notpresentationornone. - The element is neither inherently interactive (e.g.
<button>,<a href>) nor carrying an interactiverole. - The element IS inherently non-interactive (e.g.
<article>,<li>,<p>) OR has a non-interactiverole(e.g.role="article"). - The
roleattribute, when statically a literal string, is not in the ARIA abstract role set (command,composite,input,landmark,range,roletype,section,sectionhead,select,structure,widget,window).
Examples of incorrect code for this rule:
Examples of correct code for this rule:
Rule Options
handlers
Type: string[]. Default: the union of focus, image, keyboard, and
mouse event handlers — onFocus, onBlur, onLoad, onError,
onKeyDown, onKeyPress, onKeyUp, onClick, onContextMenu,
onDblClick, onDoubleClick, onDrag, onDragEnd, onDragEnter,
onDragExit, onDragLeave, onDragOver, onDragStart, onDrop,
onMouseDown, onMouseEnter, onMouseLeave, onMouseMove, onMouseOut,
onMouseOver, onMouseUp.
The upstream recommended preset overrides this with ["onClick", "onError", "onLoad", "onMouseDown", "onMouseUp", "onKeyPress", "onKeyDown", "onKeyUp"]; the strict preset omits the override and uses the default.
A list of handler prop names that the rule considers an "interactive listener". Adjust to expand or shrink the rule's coverage surface — an explicit empty array disables the rule entirely.
Examples of incorrect code with { "handlers": ["onClick"] }:
Examples of correct code with { "handlers": ["onClick"] }:
Per-element allow-list
Type: string[], keyed by HTML element name. Default: not set. The
upstream recommended and strict presets set body, iframe, and
img to ["onError", "onLoad"].
Any option key other than handlers is interpreted as an HTML element
name → list of handler-prop names that are permitted on that element. The
rule filters out matching non-spread attributes before the
interactive-handler scan, so <iframe onLoad={…} /> with iframe: ["onError", "onLoad"] short-circuits, while <iframe onClick={…} />
still reports.
Examples of correct code with { "iframe": ["onError", "onLoad"] }:
Examples of incorrect code with { "iframe": ["onError", "onLoad"] }:
Resources
- WCAG 4.1.2 — Name, Role, Value
- WAI-ARIA — Usage Intro
- WAI-ARIA Authoring Practices Guide — Design Patterns and Widgets
- WAI-ARIA Authoring Practices — Keyboard Navigation Conventions
- MDN — ARIA Techniques: Using the
buttonrole