[aria-hidden="true"] elements contain focusable descendants

[aria-hidden="true"] elements contain focusable descendants

Appears in: Accessibility audits

Users of screen readers and other assistive technologies need information about the behavior and purpose of controls on your web page. Built-in HTML controls like buttons and radio groups come with that information built in. For custom controls you create, however, you must provide the information with ARIA roles and attributes. (Learn more in the Introduction to ARIA.)

Using the aria-hidden="true" attribute on an element hides the element and all its children from screen readers and other assistive technologies. If the hidden element contains a focusable element, assistive technologies won't read the focusable element, but keyboard users will still be able to navigate to it, which can cause confusion.

How Lighthouse identifies partially hidden focusable elements #

Lighthouse flags focusable elements that have parents with the aria-hidden="true" attribute:

Lighthouse audit showing focusable elements that have parents with the aria-hidden attribute

An element is focusable when keyboard users can navigate to it using the Tab key. Focusability differs somewhat across browsers, but in general, the following elements are focusable:

  • <a>
  • <area>
  • <audio controls>
  • <button>
  • <iframe>
  • <input>
  • <select>
  • <summary>
  • <textarea>
  • <video controls>
  • Any element with the contentEditable attribute
  • Any element with a tabindex set to a numeric value other than -1

For a complete breakdown of cross-browser focus behavior, see ally.js's Focusable Elements - Browser Compatibility Table.

The Lighthouse Accessibility score is a weighted average of all the accessibility audits. See the Lighthouse accessibility scoring post for more information.

How to fix partially hidden focusable elements #

If you're hiding a container element on your page using aria-hidden, you also need to prevent users from navigating to any focusable elements inside that container.

One way to do that is to use JavaScript to apply a tabindex="-1" attribute to all focusable elements in the container. However, as implied by the list above, a query that captures all focusable elements can get complicated quickly.

If you're hiding the container element from sighted users, consider using one of the following strategies instead:

  • Add a hidden attribute to the container element.
  • Apply the display: none or the visibility: hidden CSS property to the container element.

If you can't visually hide the container element—for example, if it's behind a modal dialog with a translucent background—consider using the WICG's inert polyfill. The polyfill emulates the behavior of a proposed inert attribute, which prevents elements from being read or selected.

Caution: The inert polyfill is experimental and may not work as expected in all cases. Test carefully before using in production.

Resources #

Last updated: Improve article