How to fix aria-hidden on the page body?

aria-hidden-body page

The issue

A screen reader user lands on the page and finds nothing to read. Every heading, link and form field is still on screen, but aria-hidden="true" on the <body> has removed all of it from the accessibility tree. For that user the page is empty.

The cause is usually a script that hides the page behind a modal or a menu and never removes the attribute, or that runs before the content it meant to target exists. Occasionally it is in the template itself. WCAG 4.1.2 requires the name and role of every control to be available to assistive technology, and a hidden body makes none of them available.

Scope

The <body> element is checked once per page. It fails when it carries aria-hidden="true". Probeo reads the page as it is after loading, so an attribute a script adds later, such as when a modal opens, isn’t seen.

How to check you have it

  • In probeo: the page reports aria-hidden-body, “aria-hidden="true" must not be present on the document body”, with critical impact.
  • By hand: view the page source and read the <body> tag. In DevTools, check the live <body> too, after opening and closing any modal or menu.
  • With a tool: axe DevTools reports the same rule id. With aria-hidden on the body, the accessibility pane in Chrome or Firefox DevTools shows the page’s content missing from the tree.

The fix

Remove aria-hidden from the <body>, and hide only the parts of the page that should be hidden.

When a modal is open, hide the content behind it rather than the body that contains the modal. The native <dialog> element opened with showModal() does this for you. Otherwise put the page content in its own container and set inert on that container while the modal is open, removing it when the modal closes.

<body>
  <div id="page" inert>…</div>
  <div role="dialog" aria-modal="true" aria-labelledby="dlg-title">…</div>
</body>

Done when: the <body> has no aria-hidden attribute in any state of the page, and the check above comes back clean.

Do not

  • Do not set aria-hidden on <body> or <html> to hide content behind a modal.
  • Do not leave a script’s cleanup to run only on one of the ways a modal can close.

FAQ

Why does probeo rate this critical?

Because nothing on the page is left for assistive technology. Most accessibility issues affect one element; this one affects all of them at once.

What if the attribute is added only while a modal is open?

Probeo sees the page as it is after loading, so it reports the attribute only when it is there at that point. A body hidden by a script while a modal is open isn’t reported, but it still hides the modal from screen readers, so check it by hand.

Is aria-modal="true" enough on its own?

It tells assistive technology to treat the dialog as modal, and many screen readers then ignore the content behind it. Support varies, so keep the background unreachable with inert or the native <dialog> as well.

Which product detects this

Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.