Skip to main contentSkip to docs navigation

Visually hidden

Helpers for visually hiding elements while keeping them accessible to screen readers.

On this page
@layer helpers

.visually-hidden hides an element visually while keeping it accessible to screen readers. It is commonly used for text that provides context for icon-only controls. .visually-hidden-focusable reveals the element when it receives keyboard focus — useful for skip links. Applied to a container, the :focus-within selector reveals the container when any child receives focus.

Title for screen readers

Skip to main content
A container with a focusable element.
HTML
<h2 class="visually-hidden">Title for screen readers</h2>
<a class="visually-hidden-focusable" href="#content">Skip to main content</a>
<div class="visually-hidden-focusable">A container with a <a href="#">focusable element</a>.</div>

CSS

Both classes delegate to the visually-hidden() mixin — .visually-hidden unconditionally, .visually-hidden-focusable only when the element lacks focus.

.visually-hidden,
.visually-hidden-focusable:not(:focus):not(:focus-within) {
  @include visually-hidden();
}

Sass mixins

Both classes are also available as Sass mixins for use in custom selectors where adding a class to markup is impractical.

SCSS
.visually-hidden-title {
  @include visually-hidden;
}

.skip-navigation {
  @include visually-hidden-focusable;
}
/// Hide an element visually while keeping it accessible to screen readers.
/// See: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/
/// See: https://kittygiraudel.com/2016/10/13/css-hide-and-seek/
@mixin visually-hidden() {
  width: $utility-pixel-1 !important;
  height: $utility-pixel-1 !important;
  padding: 0 !important;
  margin: -1 * $utility-pixel-1 !important; // Fix for https://github.com/twbs/bootstrap/issues/25686
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;

  // Fix for positioned table caption that could become anonymous cells
  &:not(caption) {
    position: absolute !important;
  }
}

/// Show a visually-hidden element when it (or a descendant) has focus.
/// Useful for "Skip to main content" links.
/// See: https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
@mixin visually-hidden-focusable() {
  &:not(:focus):not(:focus-within) {
    @include visually-hidden();
  }
}