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: