Hiding content changes who can perceive or operate it. Choose a technique based on whether the content should be available visually, to assistive technologies, to keyboard users, or to nobody in the current state.

Do not treat CSS or ARIA as access control. If a person is not authorized to receive content, do not render or send it to the browser.

Choose the intended result

Effects of common content-hiding techniques
Technique Visually rendered In the accessibility tree Keyboard operable Typical use
Do not render the content No No No Content that is unauthorized, irrelevant, or unnecessary.
hidden, .hidden, or display: none No No No Content that is not relevant in the current interface state.
.invisible or visibility: hidden No, but its layout space remains No No Rare cases where hidden content must continue to occupy space.
.visually-hidden No Yes Only if the element is normally focusable Concise text needed by assistive technologies but not visually.
.visually-hidden.focusable When focused Yes Yes Skip links and similar controls that appear on keyboard focus.
aria-hidden="true" Yes No Potentially, which is dangerous Decorative or redundant visible content with no interactive descendants.
inert Yes, unless separately obscured No No A temporarily inactive subtree that is also visually shown as inactive.

The table describes normal browser behavior. Test the rendered component because CSS overrides, scripting, shadow DOM, and third-party code can change the result.

Use Drupal's hiding utilities

Drupal core provides the .hidden, .visually-hidden, .visually-hidden.focusable, and .invisible classes in the System module's base styles. Use these classes instead of copying their CSS into a theme or module. A copied implementation can become inconsistent with core.

When configuring an entity display, the field label options distinguish Hidden from Visually Hidden. Use Hidden only when the label is not needed to identify or understand the field. Use Visually Hidden when the label should remain in the rendered content for assistive technologies.

Visible labels and headings usually benefit more people than visually hidden ones. Do not hide them merely to simplify a layout. Placeholder text is not a replacement for a form label.

Hide content visually but retain it for assistive technologies

Use .visually-hidden for concise text that supplies necessary context without being displayed. This content remains available to screen readers and other assistive technologies that use the accessibility tree.

<button type="button">
  <svg aria-hidden="true" focusable="false">
    <!-- Decorative close icon. -->
  </svg>
  <span class="visually-hidden">Close dialog</span>
</button>

Keep visually hidden text short and specific. It becomes part of the person's reading and navigation experience even though it is absent from the visual layout. Avoid adding instructions only for one assistive technology when the same information would help everyone.

Do not normally apply .visually-hidden directly to an interactive control. The control can remain in the keyboard order without a visible focus indicator or visible target. If a native input is visually hidden as part of a custom-styled control, its visible label or replacement surface must expose the input's focus, checked, disabled, error, and other relevant states. Prefer styling the native control when possible.

Reveal controls when they receive keyboard focus

Use .visually-hidden.focusable for a control that should be visually hidden until it or one of its descendants receives focus. The standard example is a skip link:

<a class="visually-hidden focusable" href="#main-content">
  Skip to main content
</a>

The revealed control must be clearly visible, unobscured, and usable at high zoom. Test focus as well as pointer activation. Do not use this technique to conceal controls from pointer users or to compensate for an interaction that otherwise requires a mouse.

Hide content from everyone

Use the HTML hidden attribute when content is not relevant in the current page state. Drupal's .hidden class and CSS display: none have a similar rendered result. They remove the element and its descendants from visual layout, the accessibility tree, and keyboard navigation.

<section id="additional-settings" hidden>
  ...
</section>

display: none is not inherently an accessibility problem. It becomes a problem when it removes information, labels, instructions, errors, or controls that people still need.

When JavaScript changes visibility:

Use Drupal's established components or native HTML such as details and summary before creating a custom disclosure. See Accessible JavaScript and interactive components.

Preserve layout without exposing content

Drupal's .invisible class uses visibility: hidden. The element is not visible, exposed through the accessibility tree, or keyboard operable, but its layout space remains. This is rarely the best choice. Use it only when preserving that space is intentional and does not create a confusing blank area.

Opacity, clipping, off-screen positioning, transforms, and matching foreground and background colors do not reliably hide content from assistive technologies or keyboard navigation. Do not use them when the intent is to hide content from everyone.

Hide decorative or redundant content from assistive technologies

Use aria-hidden="true" only when visible content is decorative or redundant and equivalent meaning remains available. Common examples include a decorative icon next to a text label or a duplicate visual glyph inside a named button.

aria-hidden is not an alternative to hidden. It removes an element and its descendants from the accessibility tree without visually hiding them. It does not reliably remove descendants from keyboard navigation.

For a decorative image, prefer the native empty alternative text required by the image guidance rather than adding ARIA without need. See Accessible images and media.

Make a temporarily inactive region inert

The HTML inert attribute makes a subtree unavailable to pointer interaction, text selection, focus, find-in-page, and accessibility APIs. It is useful when a complete region is temporarily inactive.

inert does not provide a visual treatment. Make the inactive state visually clear or obscure the inactive region. Do not make essential content inert unless the active part of the interface provides the information and controls people need. Prefer the native disabled attribute for an individual form control.

A modal dialog opened with the native showModal() method makes the rest of the document inert automatically. Do not add a second, conflicting focus-management system without a demonstrated need.

Use hidden text for accessible names and descriptions carefully

Content directly referenced with aria-labelledby or aria-describedby can contribute to an accessible name or description even when the referenced element is hidden. This is defined by the Accessible Name and Description Computation specification.

That does not make the hidden text generally available for reading or navigation. Use a visible description when everyone needs the information. Use .visually-hidden when the text should remain available in the accessibility tree independently of a reference. Test the computed name and description in the browser's accessibility inspector and with supported assistive technologies.

Test hidden content and state changes

Automated tools can identify some focusable content inside aria-hidden regions and some incorrectly named controls. They cannot decide whether hidden content is necessary, whether equivalent information is available, or whether a state change is understandable. Complete the manual review.

Related guidance