Hiding elements accessibly

It's important to hide elements correctly to ensure screen-readers and input devices (i.e. a keyboard) cannot access them (unless you want them to).

Hide from screen-readers

Marking an element as aria-hidden="true" renders the element invisible to screen-readers.

<div aria-hidden="true">I will not be read by a screen-reader</div>

Remove from focus order/flow

Marking an interactive element with tabIndex="-1" prevents a user from using their TAB key to focus on that button, link or form control.

<a href="page.html" tabindex="-1">I cannot be tabbed to</a>

Remove everywhere and become invisible

display: none; will hide everything completely. As will marking an element with the hidden attribute but this may need extra work with CSS [hidden] {display: none !important; } to ensure elements stay hidden.

The problem with display: none; is that you cannot animate/transition it and that's why lots of developers opt for solutions like visibility: hidden; instead; to their peril.

<div style="display:none;">I may as well not be here</div>

Animating from display: none

You may soon be able to animate/transition from display: none;Watch this YouTube video - Transition to and from display:none with upcoming CSS capabilities

Remove everywhere, but remain visible

Another way is to mark an element as inert e.g. <div inert>My div</div>. This is a great solution but does not play very well with Typescript at this time of writing (January 2023).

<div inert>
  I cannot be interacted with and I will not be read by a screen-reader
</div>

Remove from DOM (Document Object Model)

With JSX you can remove the element from the DOM entirely:

{isConditionTrue && <div>My content</div>}

Once again, this is hard to animate. Plus under certain circumstances, elements toggled to/from the DOM may not interact with screen-readers the way we expect.

Things that don’t work

<a href="#" style="opacity: 0;">
  I can be tabbed to and read by a screen-reader
</a>
<a href="#" style="visibility: hidden;">
  I can be tabbed to and read by a screen-reader
</a>

Hide element visually but still accessible to screen-readers

You can have a utility class in CSS called .visually-hidden which when added to your element will render it visually hidden but still read aloud to a screen-reader.

<a href="page.html">
  Find out more
  <span class="visually-hidden"> about our sale</span>
</a>

View the CSS behind .visually-hidden

Combining aria-hidden and .visually-hidden

Sometimes we want the screen-reader to have a different experience to the visual user so we may need the visual experience to subtly differ from the aural experience.

A good example is when design team need to abbreviate or shorten words in order to make them fit the screen.

<button type="button">
  £159
  <span aria-hidden="true">pp</span>
  <span class="visually-hidden">per person</span>
</button>

View the CSS behind .visually-hidden

In the above example, visually we see '£159 pp' but the screen-reader should read '£159 per person'.

Further reading:

  1. Introducing inert
  2. a11y project - How to hide content
  3. Hiding content responsibily
  4. Hiding visually with CSS

Want to work with us?

Let’s talk about your project