About This Accessibility Rule
Why This Matters
Web pages often embed content using iframe or frame elements — for ads, third-party widgets, embedded forms, video players, or even internal application components. Each frame is essentially its own document with its own DOM. If axe-core is not running inside those frames, any accessibility violations within them go completely undetected.
This is classified as a critical user impact issue — not because the frame itself is inaccessible, but because undetected violations inside frames can affect all users with disabilities. Blind users relying on screen readers, sighted keyboard-only users, and deafblind users could all encounter barriers hidden within untested frame content. Missing form labels, broken focus management, insufficient color contrast, or missing alternative text inside frames would remain invisible to your testing process.
This rule is a Deque best practice rather than a specific WCAG success criterion. However, the violations that go undetected inside untested frames can relate to numerous WCAG criteria, including 1.1.1 (Non-text Content), 1.3.1 (Info and Relationships), 2.1.1 (Keyboard), 2.4.3 (Focus Order), 4.1.2 (Name, Role, Value), and many others. Comprehensive accessibility testing requires that all content on a page is analyzed, including content within frames.
How the Rule Works
When the iframes configuration property is set to true, axe-core attempts to run inside every iframe and frame element on the page. The rule uses both frame and iframe selectors to check whether the axe-core script is present in each frame’s document. If axe-core is not found inside a frame, the rule returns a “needs review” result for that element.
The rule operates at the page level — meaning results from nodes across different frames are combined into a single result when the entire page is tested. An optional after function processes results from all frames together.
How to Fix It
There are several approaches to ensure frames are properly tested:
-
Use axe-core’s built-in iframe support. When running axe-core programmatically, set the
iframesoption totrue(this is the default). axe-core will automatically attempt to communicate with frames to gather results — but the axe-core script must be present in each frame for this to work. -
Inject axe-core into all frames. If you control the frame content, include the axe-core script in those documents. If you’re using a testing framework like Selenium, Puppeteer, or Playwright, inject the axe-core script into each frame before running the analysis.
-
Use axe DevTools browser extension. The axe DevTools extension handles frame injection automatically in most cases, making it the simplest option for manual testing.
-
For third-party frames you don’t control, acknowledge that testing coverage is limited and consider testing the third-party content separately, or document it as an area requiring manual review.
Examples
Frame that triggers the issue
An iframe is present on the page, but axe-core is not loaded inside it. The content within the frame remains untested:
<main>
<h1>Our Application</h1>
<iframe src="https://example.com/embedded-form" title="Contact form"></iframe>
</main>
If https://example.com/embedded-form does not have axe-core loaded, axe will flag this frame as needing review.
Correct setup with axe-core injected
When using a testing tool like Playwright, ensure axe-core is injected into all frames:
const { AxeBuilder } = require('@axe-core/playwright');
// AxeBuilder automatically analyzes iframe content
const results = await new AxeBuilder({ page })
.analyze();
Frame content that includes axe-core
If you control the frame source, include the axe-core script directly:
<!-- Content inside the iframe document -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Embedded Form</title>
<script src="/vendor/axe-core/axe.min.js"></script>
</head>
<body>
<form>
<label for="email">Email address</label>
<input type="email" id="email" name="email">
<button type="submit">Subscribe</button>
</form>
</body>
</html>
Properly structured frame on the parent page
Always ensure your frames have descriptive title attributes so users understand their purpose:
<iframe src="/embedded-form.html" title="Newsletter subscription form"></iframe>
This won’t fix the axe-core injection issue by itself, but it ensures the frame is accessible while you work on getting full test coverage inside it.
Learn more:
Help us improve our guides
Detect accessibility issues automatically
Rocket Validator scans thousands of pages with Axe Core and the W3C Validator, finding accessibility issues across your entire site.