For each web page, is hidden content meant to be ignored by assistive technologies?

A dropdown menu opens on click. For a sighted user, options appear. For a screen reader user, if the content remains marked aria-hidden="true", it does not exist. The menu has opened, the screen reader remains silent.

This criterion distinguishes two legitimate situations. Either hidden content must remain ignored by assistive technologies — an animated visit counter, a decorative illustration — and in this case the masking is intentional. Or hidden content will become useful at some point — a modal, a submenu, an accordion panel — and it must be restorable: via a keyboard action on an element preceding the content, or via programmatic focus repositioning.

The masking technique directly determines accessibility. display: none and the hidden attribute remove the node from the accessibility tree. aria-hidden="true" does the same without changing visual rendering. visibility: hidden also removes content from AT. Conversely, the .sr-only class hides visually while keeping content readable by screen readers.

Check each element bearing hidden, aria-hidden, or CSS masking styles. One single question: is this element meant to remain invisible to AT? If it must one day become accessible, is the mechanism to achieve this keyboard-operable?

Un test to verify the correct handling of hidden content

Accessibility of hidden content to AT

  1. Identify all hidden content on the page: elements with the hidden attribute, with aria-hidden="true", or with CSS masking styles (display: none, visibility: hidden, .sr-only class, etc.).
  2. For each hidden content, choose between two cases:
    • Case A — Intentionally ignored: the content adds nothing to AT users (decorative animation, statistics counter). The masking is justified. ✓
    • Case B — Temporarily masked: the content will be useful once revealed (modal, submenu, accordion). Verify that one of two conditions is met: a. A keyboard action (or pointing device) on an element located before the content in the DOM reveals this content to AT. b. A JavaScript function repositions focus on the content when it becomes relevant.
  3. If all hidden content falls under Case A or Case B properly implemented, the test is validated. A single piece of content meeting neither case is enough to fail the test.

Examples

❌ Non-compliant : Modal permanently hidden from AT on opening

<button onclick="showModal()">Open terms</button>
 
<div id="modal" aria-hidden="true">
  <h2>Terms and conditions of use</h2>
  <p>By using this service, you accept our terms.</p>
  <button onclick="closeModal()">Close</button>
</div>
 
<script>
function showModal() {
  document.getElementById('modal').style.display = 'block';
  // aria-hidden="true" remains in place — content is never restored
}
function closeModal() {
  document.getElementById('modal').style.display = 'none';
}
</script>

The modal becomes visible on screen, but aria-hidden="true" is never removed. A screen reader user activates the button, nothing changes in the accessibility tree. The terms and conditions — potentially mandatory content — are completely inaccessible.

✅ Compliant : Accessible modal with aria-hidden removal and focus management

<button id="open-btn" onclick="showModal()">Open terms</button>
 
<div id="modal" aria-hidden="true" role="dialog" aria-modal="true" aria-labelledby="modal-title">
  <h2 id="modal-title">Terms and conditions of use</h2>
  <p>By using this service, you accept our terms.</p>
  <button id="close-btn" onclick="closeModal()">Close</button>
</div>
 
<script>
function showModal() {
  const modal = document.getElementById('modal');
  modal.removeAttribute('aria-hidden');
  modal.style.display = 'block';
  document.getElementById('close-btn').focus();
}
function closeModal() {
  const modal = document.getElementById('modal');
  modal.setAttribute('aria-hidden', 'true');
  modal.style.display = 'none';
  document.getElementById('open-btn').focus();
}
</script>

On opening, aria-hidden is removed and focus moves into the modal. The screen reader immediately announces the dialog title. On closing, focus returns to the trigger button. Complete cycle, no loss of information.

✅ Compliant : Intentionally ignored content: counter animation

<div aria-hidden="true" class="stats-counter-animation">
  <span class="counter" data-target="15420">0</span> visits
</div>
<p>More than <strong>15,000 users</strong> trust our service.</p>

The counter animation (0 → 15,420) adds nothing to AT: a screen reader would read every intermediate value, creating unnecessary noise. The actual information is provided in the following paragraph as static text. aria-hidden="true" is intentional and justified here.

Tips and pitfalls

⚠️ aria-hidden propagates to all descendants without exception

Setting aria-hidden="true" on a parent <div> hides all its children from AT, even if they carry role, aria-label, or other explicit ARIA attributes. Chrome DevTools explicitly indicate it: « Accessibility node not exposed, aria-hidden is true on ancestor ». Always verify scope before applying the attribute to a container.

⚠️ An aria-hidden element can remain keyboard-focusable

aria-hidden="true" does not remove the element from the keyboard tab order. A button or link in a panel hidden from AT will still receive focus with Tab. The user ends up in a black hole: the cursor disappears visually without announcement. If content must be hidden from AT, its interactive children must also be made non-focusable via tabindex="-1" or the inert attribute.

💡 Audit with the browser's accessibility tree

In Chrome or Firefox DevTools, the Accessibility tab displays the accessibility tree in real time. An element absent from the tree or marked « not exposed » is effectively ignored by screen readers. This is the fastest verification, more reliable than full testing with a screen reader for this criterion.

⚠️ .sr-only exposes content to AT, not the reverse

The .sr-only class (or .visually-hidden) hides visually while keeping content in the accessibility tree. The error occurs when applied to decorative content: the screen reader then announces unnecessary noise. Criterion 10.8 cuts both ways: content useful to AT but hidden from AT, and decorative content exposed to AT, are both problems.

⚠️ CSS animations alone do not hide from AT

An element with opacity: 0 or transform: scale(0) generally remains in the accessibility tree and will be read by screen readers. If your transition animation leaves an element at opacity: 0 between two states, add aria-hidden="true" during that intermediate state, or use display: none at the end of the transition.

Frequently asked questions

What is the difference between display: none and aria-hidden="true" for masking content according to RGAA?

display: none and the hidden attribute mask content visually AND remove it from the accessibility tree. aria-hidden="true" removes only from the accessibility tree — the content remains visible on screen. Criterion 10.8 applies to both: if this content is not meant to remain ignored by AT, it must be made accessible via a keyboard action or focus repositioning, regardless of the masking technique.

How do you verify that masked content is properly ignored by assistive technologies?

Open DevTools, inspect the element, access the Accessibility tab. An element absent from the accessibility tree or displaying « not exposed » is effectively ignored. For dynamic content (modals, menus), trigger the opening and verify that the tree updates, that aria-hidden is removed, and that focus properly moves into the revealed content.

How do you evaluate a collapsed accordion according to RGAA criterion 10.8?

Yes, under two conditions. The trigger button must precede the panel in the DOM and carry aria-expanded to indicate state. On opening, content must be restored to AT: either by removing aria-hidden (content follows the button immediately in the AT flow), or by repositioning focus in the panel. The presence of aria-expanded alone is insufficient if content remains marked aria-hidden="true".

How does opacity: 0 affect content perception by assistive technologies?

Not reliably. An element with opacity: 0 generally remains in the accessibility tree and will be read by screen readers. To hide from AT, use display: none, hidden, or aria-hidden="true". To hide visually while maintaining accessibility, use .sr-only. transform: scale(0) behaves like opacity: 0: visible to AT.

How does RGAA criterion 10.8 apply to third-party components like chatbots and cookie banners?

Yes, it applies to the entire page, including external widgets. These components frequently generate 10.8 violations because they handle aria-hidden or focus poorly when displaying their panels. If you do not control the code, report the issue to the provider and document the exception in your accessibility statement with a correction timeline.

References