Skip to content

Linter Rule: No nested interactive elements

Rule: a11y-nested-interactive-elements

Description

Disallow nesting interactive elements inside other interactive elements. Interactive controls such as <button>, <summary>, <input>, <select>, <textarea>, or <a> must not contain other interactive elements.

Rationale

Nesting interactive elements produces invalid HTML, and assistive technologies, such as screen readers, might ignore or respond unexpectedly to such nested controls.

Exceptions

  • <a> inside <summary> is allowed.
  • <input type="hidden"> is not considered an interactive element.

Examples

✅ Good

erb
<button>Confirm</button>
erb
<a href="/about">About</a>
erb
<div><a href="/about">About</a></div>
erb
<summary><a href="/about">About</a></summary>
erb
<button><input type="hidden" name="token" /></button>
Use `<input>` instead of self-closing `<input />` for HTML compatibility. (html-no-self-closing)

🚫 Bad

erb
<button><a href="https://github.com/">Go to GitHub</a></button>
erb
<a href="/about"><button>Click</button></a>
erb
<button><select><option>A</option></select></button>
erb
<button><input type="text" /></button>
Use `<input>` instead of self-closing `<input />` for HTML compatibility. (html-no-self-closing)
Add an `autocomplete` attribute to improve form accessibility. Use a specific value (e.g., `autocomplete="email"`), `autocomplete="on"` for defaults, or `autocomplete="off"` to disable. (html-input-require-autocomplete)

References

Released under the MIT License.