The aria-hidden-focus rule flags content hidden from assistive technology with aria-hidden="true" that can still receive keyboard focus. A screen reader user tabs onto a link that, as far as their software is concerned, does not exist – and hears nothing, or something out of context. The fix is to hide the content from the keyboard as well, usually with the inert attribute.
What the rule means
aria-hidden="true" removes an element and everything inside it from the accessibility tree. It does not remove anything from the tab order. So a link inside still takes focus when somebody presses Tab, but assistive technology has been told to ignore it: its name, its role and its purpose are gone. That breaks 4.1.2, which requires every control to expose a name and a role.
The rule passes when every focusable element inside an aria-hidden container is taken out of the tab order – by inert, disabled, tabindex="-1" or by hiding it with display: none or visibility: hidden.
Who is affected
Screen reader users first: focus lands somewhere their software refuses to describe. Sighted keyboard users are affected too when the hidden content is also off-screen, because every Tab stop in a closed menu is one they cannot see.
Why the check fails
- Off-canvas menus marked
aria-hidden="true"while closed, with their links still tabbable. - Modal dialogs that set
aria-hiddenon the page behind them but leave its links in the tab order. - Carousels that hide inactive slides with
aria-hiddenwhile their links and buttons stay focusable. - Decorative wrappers around icons that contain a real link or button.
- Copies for animation – a duplicated marquee or ticker hidden from screen readers, links included.
How to fix it
Use inert on anything you hide: it takes the content out of the tab order and out of the accessibility tree in one attribute, and it is supported in all current browsers.
<!-- Before: hidden from screen readers, still reachable by Tab -->
<nav class="offcanvas" aria-label="Menu" aria-hidden="true">
<a href="/shop/">Shop</a>
<a href="/account/">Account</a>
</nav>
<!-- After: inert hides it from both, until the menu opens -->
<nav class="offcanvas" aria-label="Menu" inert>
<a href="/shop/">Shop</a>
<a href="/account/">Account</a>
</nav>
When the menu opens, remove inert again (menu.inert = false). For a modal, <dialog> opened with showModal() makes the rest of the page inert for you. If you must keep aria-hidden, set tabindex="-1" on every focusable child – and remember to restore it.
How to test it manually
- Close every menu, dialog and carousel slide, then press Tab through the page. Does focus land on anything you cannot see?
- In the browser's developer tools, inspect the focused element's accessibility properties. "Ignored" or no name means it is hidden from assistive technology.
- With a screen reader running, tab through the same places and listen for silence or out-of-context links.
- Open the components again and check that their content is reachable once visible.
Related WCAG criterion
4.1.2 Name, Role, Value, Level A. Related: 2.4.3 Focus Order, because focus visits content that is not really there, and 1.3.1 Info and Relationships.
How Reviseberg reports it
Reviseberg runs aria-hidden-focus on every crawled page. The issue list shows the rule with its severity, WCAG 4.1.2, the number of affected elements and pages, and the points a fix gets you back; the detail view shows the selector and HTML snippet of the hidden container. Because the cause is usually one component in the template, one fix often clears every page at once. Where the hidden content is also off-screen, the keyboard agent's walk may show the same menu as undefined on the journey you define.