Hiding content accessibly
This post is over two years old, the content may be out of date.
There are often situations where we need to hide content on a page, either temporarily or permanently. The method you use for hiding content can have a big impact on accessibility, so this post will discuss when to use particular techniques.
There are generally 3 scenarios where we want to hide content:
- We want to hide content for everyone (including people using screen readers).
- We want to hide content visually (but not from screen readers).
- We want to hide content from screen readers (but not visually).
Hiding content for everyone
Common situations where you want to hide content from everyone, including sighted keyboard users and people using screen readers, are closed navigation menus, tooltip text and collapsed accordions.
The CSS styles below will prevent the element displaying visually on the page, will be ignored by screen readers, and will prevent keyboard users tabbing to the content.
.hide-for-all { display: none; }
.hide-for-all { visibility: hidden; }
The difference between display: none;
and visibility: hidden;
is that hidden elements are not removed from the document flow, so will retain its physical space on the page.
A common mistake when hiding content is to use opacity: 0;
when the intention is to hide the content from everyone. Although this styling removes the content visually, it is still announced by screen readers and potentially focusable by the keyboard.
Hiding content visually
There are two main situations when you want to hide content visually:
- When you never want the content to be visible on the page.
- When you want the content to become visible when focused by the keyboard.
Never visible
There are times when the visual information in a design is not sufficient for screen readers users. A common example of this is form inputs that aren't given visual labels.
Labels are crucial for screen reader users to understand and successfully complete forms. So in a situation like this you could visually hide the label with CSS.
The most commonly accepted practice for modern browser support is using clip-rect.
.sr-only {
position: absolute;
height: 1px;
width: 1px;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
margin: -1px;
overflow: hidden;
padding: 0;
border: 0;
white-space: nowrap;
}
Elements with this class will not be visible on the page or take up space in the visual flow, but will announce the contents to assistive technologies.
Visible when focused
Sometimes we want to hide an element only until it receives keyboard focus.
A perfect example of this are skip-links. A skip-link is styled with CSS to remain out of view until a user tabs to the element and is then sent back off-screen when it leaves keyboard focus. This behaviour benefits sighted keyboard users, without changing the visual design for mouse users.
We use a combination of CSS properties to position the content offscreen and the :focus
pseudo element to bring the position onto the page as the element by the keyboard.
/* positioned offsceen so not visible */
.skip-link a {
position: absolute;
left: -10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}
/* appears back on screen when focused with keyboard */
.skip-link a:focus {
position: static;
width: auto;
height: auto;
}
Combined approach
An alternative approach is to combine these two methods and use the :not(:focus)
and :not(:active)
pseudo elements within the sr-only
class. This will remove the offscreen styling when an element is focused or active.
.sr-only:not(:focus):not(:active) {
position: absolute;
width: 1px;
height: 1px;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
margin: -1px;
overflow: hidden;
padding: 0;
white-space: nowrap;
}
Hiding content from screen readers
It's uncommon to need content to be hidden from screen readers only, however this can be appropriate when visual content is decorative or duplicative. An example would be SVG or font icons that are accompanied by text labels.
We can hide the icons from assistive technology using aria-hidden="true"
. This effectively has the opposite behaviour of our sr-only
class, in that it remains visually on the page while being ignored by assistive technologies.
<button>
<span class="icon-close-menu" aria-hidden="true"></span>
<span class="sr-only">Close navigation menu</span>
</button>
Further Reading
If you're interested in learning more about hiding content accessibly here are some great resources:
- Invisible Content Just For Screen Readers by WebAIM
- How to Hide Content by The A11y Project
- Inclusively Hidden by Scott O'Hara
Jess is a senior software engineer and web accessibility nerd. When she’s not writing, speaking or tweeting about tech, you’ll find her putting together lego or going on walks with her doggo.