aria-hidden Must Not Be Present on Document Body: How to Fix It
- January 10, 2025
- HTML Structure, ARIA

What this check flags
This check fails when aria-hidden="true" is set on the <body> element. Because aria-hidden cascades to every descendant, putting it on the body hides the entire page from assistive technology — a screen reader is handed a document with, effectively, nothing in it. For someone relying on that screen reader, your fully rendered page is a blank wall.
This is not a subtle degradation like low contrast. It is an all-or-nothing failure: sighted users see a normal page, screen-reader users get silence. And it is almost never intentional — it is collateral damage from code that was trying to hide something else.
A real failing example, and the fix
The usual cause is a modal or overlay script that hides the background while a dialog is open, then targets the wrong node or forgets to clean up. Here is the broken pattern:
<!-- Modal open: script hides "the rest of the page"
but points at <body> instead of a page wrapper -->
<body aria-hidden="true">
<div id="app"> ... entire site ... </div>
<div class="modal" role="dialog"> ... </div>
</body>Since the dialog is inside the hidden body, even the modal the script wanted to show gets hidden from assistive tech. The fix is to never mark the body itself. Wrap the page content in a container, hide that container when the modal opens, and keep the modal a sibling outside the hidden wrapper:
<body>
<div id="app" aria-hidden="true"> ... page content ... </div>
<div class="modal" role="dialog" aria-modal="true"> ... </div>
</body>
<script>
// On close, remove it — never leave it stuck on:
document.getElementById('app').removeAttribute('aria-hidden');
</script>Better still, modern browsers support the inert attribute, which removes an element from the accessibility tree and blocks focus and pointer events — a cleaner tool for backgrounding content behind a modal than aria-hidden alone.
aria-hidden values and what they do
Half the confusion here comes from misunderstanding what the attribute's values mean. This table clears it up:
| On the body | Effect on assistive tech | Verdict |
|---|---|---|
aria-hidden="true" | Entire page removed from the accessibility tree | Fails this check — never do this |
aria-hidden="false" | No-op on body, but a code smell worth removing | Passes, but delete it |
| Attribute absent (default) | Page is fully exposed to assistive tech | Correct state |
aria-hidden="true" on a decorative child | Only that child is hidden | Fine — and often correct |
inert on a background wrapper | Hides + blocks focus/pointer, body untouched | Preferred for modals |
The takeaway: aria-hidden="true" is a perfectly good tool on a decorative icon or an offscreen carousel slide. The problem is exclusively its placement on <body> (or on the root wrapper that contains everything), where it takes the whole page down with it.
How to detect it
- Run an automated checker (axe, Lighthouse). The rule "aria-hidden='true' must not be present on the document body" reports it directly with a clear pass/fail.
- Inspect the live DOM, not just the source. This attribute is frequently added by JavaScript after load, so view the rendered
<body>in DevTools while the page and any modals are open and closed. - Search your codebase for
aria-hiddenapplied todocument.bodyor to a top-level wrapper, and for scripts that set it on open without a matching removal on close. - Test with an actual screen reader (VoiceOver, NVDA). If it announces nothing on a visibly full page, a body-level
aria-hiddenis the prime suspect. - Exercise every modal, drawer, and overlay open-and-close cycle — the bug often only appears in the "stuck on after close" state.
How to fix it
- Remove
aria-hiddenfrom<body>entirely. The body should never carry it. - To background page content behind a modal, wrap that content in a container and apply
aria-hidden(or, better,inert) to the wrapper — keeping the modal outside it. - Guarantee cleanup: whatever adds the attribute on open must remove it on close, including on error paths and route changes.
- Audit third-party widgets and modal libraries; some manage focus by hiding the body and never restore it. Configure or patch them to target a wrapper.
- Re-test with a screen reader after the change to confirm the page is announced again.
FAQ
Is aria-hidden always bad?
Not at all. On a decorative icon, a duplicate offscreen element, or an inactive carousel slide, aria-hidden="true" is exactly right — it stops assistive tech from announcing noise. The failure is specific to putting it on the <body> (or the single wrapper that holds the whole page), which hides everything.
Why does one attribute hide the whole page?
aria-hidden inherits down the tree. Setting it on an ancestor hides that element and all of its descendants from the accessibility tree. Since <body> is the ancestor of every visible thing on the page, hiding it hides the lot.
What should I use to hide the background behind a modal?
Apply the hiding to a content wrapper, never the body, and keep the modal as a sibling outside that wrapper. The inert attribute is the modern best choice because it removes the background from the accessibility tree and also blocks focus and clicks, so keyboard users cannot tab into hidden content.
It is added by JavaScript, so it is not in my HTML source. Does that matter?
No — assistive tech reads the live DOM, not your original source. If a script sets aria-hidden="true" on the body at runtime, the page is hidden regardless of what the source file says. Always inspect the rendered DOM.
Does this hurt SEO?
Search crawlers largely ignore aria-hidden for indexing, so ranking impact is minimal. The real cost is a broken experience for screen-reader users and the legal and reputational exposure that comes with it. It sits in the same family as other structural ARIA mistakes — see required ARIA attributes and the broader accessibility and SEO overview.
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.







