R3.09.2visual versus semantic hidingdesign

Visual hiding and semantic hiding are different operations

Aliases: visually hidden · aria-hidden · inert · sr-only · clipped off-screen

What it is

Taking a region off the screen and taking it out of assistive technology are two independent switches. Visual hiding changes paint: clip, one-pixel shrink, transparency, off-viewport shift. The node stays in the accessibility tree and its name can still be computed. Semantic hiding changes exposure: display: none, visibility: hidden, hidden, aria-hidden, and inert remove the node from the tree or mark it unavailable. Invisible does not imply unspoken; unspoken does not imply invisible.

The verb "hide" collapses the two. For a screen-reader user they are opposite gifts: an sr-only label is meant only for them; aria-hidden="true" on a visible button takes away something sighted users still have.

Why it happens

Paint and the accessibility tree take different inputs. Opacity, clipping, and transform off-screen affect compositing; the platform API still receives the node, a screen reader will speak it, and Tab may still land on it unless focusability is turned off separately. display: none and hidden drop the node from both paint and the tree; visibility: hidden is typically unexposed; aria-hidden drops it from the tree while the pixels can remain; inert makes a whole subtree unfocusable and unclickable, which is semantic unavailability.

The switches are orthogonal, so they produce four outcomes: visible and spoken (ordinary controls), visible but unspoken (aria-hidden over visible UI), invisible but spoken (sr-only labels — the legitimate way to supply a name), invisible and unspoken (a truly closed panel). Failures are almost always the wrong pair: visually hiding an error so the screen reader never hears it; aria-hidden on a visible close button so keyboard focus still lands on a control that "does not exist".

Where it stops holding

Off-screen ads, captchas, or repeated decoration that should not be spoken will leak through visual hiding; those need semantic hiding or not rendering at all. Print CSS and opacity: 0 entrance motion still expose the node mid-animation; if the content is not ready to be read, a semantic switch is required — "temporarily unseen" is not "temporarily unread". Stacking inert or aria-hidden on a node that already holds focus can trap focus in a region assistive technology can no longer see; that is a focus problem hiding attributes cannot fix alone. Search engines and copy-paste do not use the accessibility tree; semantic hiding does not delete the text from the DOM.

Applying it

  • Text that must become an accessible name without taking layout space uses paint-only sr-only / clip techniques, not display: none or aria-hidden.
  • UI that should be fully unavailable (the page behind a closed overlay, an inactive tab panel) uses semantic hiding or inert, not a transparent scrim alone.
  • Never set aria-hidden="true" on a control that is still visible and clickable. Never visually-only hide the text that errors, status, or names depend on.
  • How to check: for the same region, look at pixels and the accessibility tree. Name which of the four combinations you actually have. Then Tab through: unspoken nodes must not take focus; spoken-but-invisible nodes must be exactly the ones you meant to leave for assistive technology.

Related

  • Same group: R3.09.1 Without name, role, and state, assistive technology cannot express a control · R3.09.3 Dynamic changes need to be announced, not merely restyled
  • Nearby: R3.01 Semantic Structure · J2.09 Semantic Structure
  • Search terms: visually hidden · aria-hidden · inert · semantic hiding

Cards in the same group

Quick Actions

Share

Share this page

ios_share

https://hci.top/en/handbook/R3.09.2