Hiding Content Accessibly

Posted

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:

  1. We want to hide content for everyone (including people using screen readers).
  2. We want to hide content visually (but not from screen readers).
  3. 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:

Jess Budd informal headshot

Jess Budd is a front-end developer, accessibility consultant and digital producer. She co-organises a meetup group for front-end developers, mentors women learning to code and has a love of technology and doggos.