Frames Must Not Block Focus: How to Fix It

No Comments
Frames must not block focus: how to fix it

This check flags any <frame> or <iframe> that a keyboard user can never step into — almost always because someone slapped tabindex="-1" on the frame itself while it holds links, buttons, or form fields. The stakes are blunt: a person who navigates by Tab (motor-impaired users, screen-reader users, anyone whose mouse just died) hits your embedded form, video controls, or map and simply cannot reach a single control inside it.

What actually breaks

A frame is a doorway. The content inside it — a booking widget, a payment iframe, an embedded document viewer — has its own focusable elements. When you set tabindex="-1" on the frame element, you pull the whole doorway out of the tab order, and every interactive thing behind it goes dark for keyboard users. The visual layout looks fine. Sighted mouse users never notice. Then an audit (or a support ticket) tells you 8% of your checkout traffic can't submit the embedded card form.

The other common variant: a wrapper <div> around the iframe carries tabindex="-1", or a rogue global focus script re-sets tabindex on load. Same result, harder to spot.

Real failing example

<!-- Embedded appointment booker. Keyboard-dead. -->
<iframe
  src="https://booking.example.com/widget"
  title="Book an appointment"
  tabindex="-1"
  width="100%"
  height="620">
</iframe>

<!-- Variant: the trap is on the wrapper -->
<div class="embed-shell" tabindex="-1">
  <iframe src="/maps/store-locator" title="Store locator"></iframe>
</div>

Tabbing through this page skips straight past the booker. The buttons inside booking.example.com/widget are reachable in isolation, but the negative tabindex on the host frame removes the entry point.

The fix

<!-- Remove the tabindex trap entirely. -->
<iframe
  src="https://booking.example.com/widget"
  title="Book an appointment"
  width="100%"
  height="620">
</iframe>

<div class="embed-shell">
  <iframe src="/maps/store-locator" title="Store locator"></iframe>
</div>

By default an iframe with interactive content is already in the tab order — you do not add anything, you remove the thing blocking it. Keep the title attribute; that is what a screen reader announces when focus lands on the frame. If you genuinely have a decorative, non-interactive iframe (an ad pixel, an analytics beacon), the correct move is aria-hidden is not valid on a focusable iframe — instead give it an empty title only if it has nothing a user needs, and never put focusable controls inside a hidden frame.

tabindex on frames: what each value does

ValueEffect on the frameEffect on content insideUse it?
tabindex="-1"Frame skipped in Tab order; only focusable via scriptInteractive children become unreachable by keyboardNever on interactive frames
tabindex="0"Frame joins natural DOM orderChildren reachable normallyRedundant — iframes are already focusable; harmless
tabindex="5" (positive)Frame jumps to a manual priority slotWrecks the surrounding tab sequenceNo — see the positive-tabindex trap
No tabindexDefault: frame is in tab orderChildren reachable normallyCorrect default

How to detect it

  1. Keyboard walk. Load the page, put your mouse away, press Tab repeatedly. If focus never lands on or inside the frame, you have the bug. This is the ground truth — do it first.
  2. axe DevTools. Run the axe browser extension; it reports the frame-focusable-content rule when a frame with focusable descendants is itself removed from tab order.
  3. Lighthouse. Chrome DevTools → Lighthouse → Accessibility category flags focusable-content-in-frames failures with the offending selector.
  4. DOM query. In the console, run document.querySelectorAll('iframe[tabindex="-1"], frame[tabindex="-1"]') and inspect each hit for interactive content.

How to fix it

  1. Find the negative tabindex on the frame or its wrapper.
  2. Delete it. Do not replace it with tabindex="0" unless you have a specific reason — the default already works.
  3. Confirm the frame still carries a meaningful title.
  4. Re-run the keyboard walk. Tab should now enter the frame and reach every control inside.
  5. If a script re-applies the tabindex on load, patch the script — a CSS override cannot fix a JS-set attribute.

Frequently asked questions

Why would anyone put tabindex="-1" on an iframe in the first place?

Usually to stop a "focus jump" flicker, or copy-pasted from a modal pattern where -1 is used to make a container programmatically focusable. In modals you focus the container by script; you never leave interactive children stranded. On a plain content iframe the value has no upside and one large downside.

Does this hurt SEO or only accessibility?

Directly, it is an accessibility failure that shows up in WCAG audits (2.1.1 Keyboard). Indirectly it feeds the engagement and quality signals search engines increasingly read, and it is exactly the kind of thing an agentic browser trips over. See Accessibility and SEO for where the two genuinely overlap.

My iframe is decorative — can I safely remove it from tab order?

Only if it truly has zero interactive content. A tracking pixel or a purely visual embed can stay out of the tab order. The moment there is a link or button inside, it must be reachable.

What about tabindex on the elements inside the frame?

That is a different failure. If controls inside a reachable frame are themselves skipped, look at Focusable Elements Need Roles and the aria-hidden Must Not Contain Focusable Elements check.

How do I test this at scale across a big site?

Run axe or Lighthouse in CI, and for spot checks use the workflow in Test Frames with Accessibility Tools. Related keyboard-reachability checks live in Scrollable Region Keyboard.

Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.

About SEO ProCheck

Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.

Work With Me

Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.

Subscribe to our newsletter!

More from our blog