Who it affects
Someone booking a dentist appointment with the keyboard Tabs down the page, reaches the embedded booking form, and focus jumps over it to the footer. The form is right there on screen and they cannot type into it.
Someone using a screen reader may be able to read the text in the frame but cannot press its buttons, because focus never enters it.
The developer who added the attribute to stop a focus ring appearing round the frame cannot see the problem with a mouse and does not hear about it until a patient phones the surgery to book.
Broken versus fixed
The broken markup is shown as code rather than rendered, because the effect is in how it is announced or handled, not how it looks.
<h2>Book an appointment</h2>
<iframe src="https://booking.example/mill-street-dental" title="Book an appointment" tabindex="-1"></iframe>
<p><a href="/contact">Or phone the surgery</a></p>
Tab from the heading goes straight to the phone link. The booking form inside the frame is unreachable from the keyboard.
<h2>Book an appointment</h2>
<iframe src="https://booking.example/mill-street-dental" title="Book an appointment"></iframe>
<p><a href="/contact">Or phone the surgery</a></p>
Tab enters the frame, moves through the form fields inside it, then comes out the other side to the phone link.
Test it by hand in two minutes
- Click just above the frame and press Tab. Focus should move into the frame's first control, with a visible outline.
- Right click the frame, choose Inspect, and look for tabindex="-1" on the iframe element.
- Keep pressing Tab inside the frame. Focus should pass through its controls and leave again; it should not skip them and it should not get stuck.
- If the frame is display only (a map tile, an advert), check there are no buttons or links inside it. If there are, they are the problem.
The fix
<iframe src="https://booking.example/mill-street-dental" title="Book an appointment" tabindex="-1"></iframe>
<iframe src="https://booking.example/mill-street-dental" title="Book an appointment"></iframe>
There is almost never a reason to put tabindex on an iframe. Delete it and let the browser handle focus.
Frame that nobody should use
<iframe src="/pixel.html" tabindex="-1"></iframe>
<iframe src="/pixel.html" title="Tracking pixel" hidden></iframe>
If the frame has no content a person should use, hide it from everyone with the hidden attribute rather than only from the Tab key.
Focus ring on the frame itself
<iframe src="/map.html" title="Map" tabindex="-1"></iframe>
<iframe src="/map.html" title="Map" class="map-frame"></iframe>
<style>.map-frame:focus { outline: none; } .map-frame:focus-visible { outline: 2px solid #1d4ed8; }</style>
If the frame was given tabindex="-1" to tidy up a focus ring, style the ring instead. Keep it visible for keyboard users.
Common mistakes
- Using tabindex="-1" to stop a focus outline appearing round the frame; style the outline instead.
- Planning to focus the frame from script after adding tabindex="-1": that focuses the frame element, not the controls inside it.
- Adding tabindex="0" to the frame as well, which only adds an empty extra Tab stop.
- Hiding a frame with opacity or by moving it off screen while it still holds a form.
WCAG criteria this rule maps to
axe-core tags this rule as WCAG 2.2 level A. It is one of the checks for:
- 2.1.1 Keyboard (level A). Official W3C text.
The scanner looks for frame and iframe elements with tabindex="-1" and checks whether the document inside has focusable elements. It can only look inside frames from the same site; for a frame from another domain it cannot see the content and asks for a person to check. Automated tools find only part of the accessibility problems on a page; a pass on this rule is not a pass on the criterion.
Related rules
frame-title
An iframe is a window onto another page: a map, a video, a booking form, a payment field.
A
Scrollable areas must be reachable with a keyboard
scrollable-region-focusable
When a box has its own scrollbar, mouse users scroll it with the wheel.
A
Hidden elements must not contain anything you can Tab to
aria-hidden-focus
aria-hidden="true" tells screen readers to ignore an element, but it does not stop the Tab key reaching the links and buttons inside.
A
Frames on the same page must have different titles
frame-title-unique
If a page has several frames, each needs its own title.