Focus on an invisible element (keyboard:focus-invisible)

The keyboard:focus-invisible rule flags a Tab press that lands on an element nobody can see: it sits off-screen, is fully transparent, is hidden or has no size. The focus ring may be perfect – it is drawn where nobody is looking. The fix is to bring the element into view when it takes focus, or to take it out of the tab order while it is hidden.

What the rule means

WCAG 2.4.7 requires a visible focus indicator. If the focused element itself cannot be seen, neither can its indicator, and the keyboard user presses Tab into nowhere: nothing on screen changes, and the next Enter may trigger a link they never saw.

This is a different failure from undefined. There the element is visible and nothing marks it; here the element is not visible at all. Both fail 2.4.7. Focus that is visible but covered by a sticky header or a cookie banner is a third case, covered by 2.4.11 – and not detected by this rule.

Who is affected

Sighted keyboard users: people with motor disabilities using a keyboard or switch, people with low vision using a magnifier, and anyone who prefers the keyboard. Each invisible stop costs a Tab press and, worse, the sense of where they are. A closed off-canvas menu can hide twenty such stops before the page content.

Why the check fails

  • Skip links hidden off-screen with left: -9999px and no rule that brings them back on :focus.
  • Off-canvas menus pushed off-screen while closed, with their links still in the tab order.
  • Content hidden with opacity: 0 – closed dropdowns, carousel slides that are not showing – but still focusable.
  • Zero-size wrappers that clip focusable content, such as collapsed accordions built with height: 0; overflow: hidden.
  • Visually hidden form controls, for example a custom checkbox whose real input is transparent.

How to fix it

Either show the element when it takes focus, or make it unfocusable while it is hidden.

/* Before: the skip link stays off-screen, even with focus */
.skip-link { position: absolute; left: -9999px; }
/* After: it comes into view the moment it takes focus */
.skip-link { position: absolute; left: -9999px; }
.skip-link:focus { left: 1rem; top: 1rem; }

For a menu that is off-screen while closed, hide it properly – visibility: hidden (or the inert attribute) removes its links from the tab order until it opens:

/* Before: closed, but its links are still Tab stops */
.offcanvas { position: fixed; top: 0; left: -20rem; width: 18rem; }
/* After: closed means hidden from the keyboard too */
.offcanvas { position: fixed; top: 0; left: -20rem; width: 18rem; visibility: hidden; }
.offcanvas.is-open { left: 0; visibility: visible; }

How to test it manually

  1. Press Tab from the top of the page and watch the screen after every press.
  2. Whenever nothing visible changes, open the developer tools console and run document.activeElement to see where focus went.
  3. Open and close menus, accordions and carousels, then tab through them again in both states.
  4. Repeat at mobile width, where navigation is usually off-canvas.

2.4.7 Focus Visible, Level AA. Related: 2.4.11 Focus Not Obscured (Minimum) for focus covered by other content, and 2.4.3 Focus Order.

How Reviseberg reports it

This rule comes from Reviseberg's keyboard agent, not from axe-core. The agent walks the journey you choose with real Tab presses in Chromium and, at every step, measures the focused element: if it has no width or height, is opacity: 0 or visibility: hidden, or lies entirely above or to the left of the page, the step fails with "Focus moved to an element with no size on screen" or "Focus moved to an element that is transparent or off-screen".

The finding carries the selector, the step in the keystroke trail and, on a full crawl, a cropped screenshot. The agent measures the focused element itself, not what is drawn next to it: a custom checkbox with a transparent input and a focus ring on its label is reported too. If the ring is clearly visible, mark the finding as a false positive with that reason. Focus hidden behind another element is not detected.

  • undefined – the element is visible, but nothing marks it.
  • undefined – the page has no working skip link.
  • undefined – focusable content hidden from assistive technology.

Run the keyboard agent on your site – free report

Frequently asked questions

Is a skip link that is hidden until focused allowed?

Yes – that is the usual pattern. It only fails when it stays hidden while it has focus.

What is the difference from keyboard:focus-visible?

There the focused element is visible but not marked. Here the element itself cannot be seen, so no focus style can help.

Does display: none cause this?

No. Elements with display: none or visibility: hidden cannot take focus at all, which is why they are the right way to hide a closed menu.

Does the agent find focus behind a sticky header?

No. It checks whether the element is on screen and visible, not whether something covers it. Check that by hand against 2.4.11.

Sources

  1. W3C, Understanding SC 2.4.7 Focus Visible – https://www.w3.org/WAI/WCAG22/Understanding/focus-visible
  2. W3C, Understanding SC 2.4.11 Focus Not Obscured (Minimum) – https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum
  3. MDN, HTML inert global attribute – https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert
  4. WebAIM, Skip Navigation Links – https://webaim.org/techniques/skipnav/

See what a scan finds on your site

One page in about thirty seconds, no email needed. The full report covers up to 100 pages and a keyboard journey.