In order to code modern component designs we often need to hide then reveal elements. At other times we want to provide content to one type of user but hide it from another because it’s not relevant to their mode of browsing. In all cases accessibility should be front and centre in our thoughts. Here’s my approach, heavily inspired by Scott O’Hara’s definitive guide Inclusively Hidden.
Firstly, avoid the need to hide stuff. With a bit more thought and by using existing fit-for-purpose HTML tools, we can perhaps create a single user interface and experience that works for all. That approach not only feels like a more equal experience for everyone but also removes margin for error and code maintenance overhead.
With that said, hiding is sometimes necessary and here are the most common categories:
- Hide from everyone
- Hide visually (i.e. from sighted people)
- Hide from Assistive Technologies (such as screen readers)
Hide from everyone
We usually hide an element from everyone because the hidden element forms part of a component’s interface design. Typical examples are tab panels, off-screen navigation, and modal dialogues that are initially hidden until an event occurs which should bring them into view. Initially these elements should be inaccessible to everyone but after the trigger event, they become accessible to everyone.
For basic, non-animated show-and-hide interactions you can either:
- toggle a class which applies
display: nonein CSS; or
- toggle the boolean
hiddenattribute, which has the same effect but is native to HTML5.
Both options work well but for me using the
Here’s some CSS that supports both methods. (The
hidden attribute doesn’t strictly need this but it’s handy to regard both options as high-specifity, “trump-everything-else” overrides.)
For cases where you are animating or sliding the hidden content into view, toggle the application of CSS
visibility: hidden because this also removes the element from the accessibility tree but unlike
display, can be animated. Note that with
visibility: hidden the physical space occupied by the element is still retained, therefore it’s best to pair it with
position: absolute or
max-height: 0px; overflow: hidden to prevent that “empty space while hidden” effect. For example:
Hide visually (i.e. from sighted people)
We’ll usually want to hide something visually (only) when its purpose is solely to provide extra context to Assistive Technologies. An example would be appending additional, visually-hidden text to a “Read more” link such as “about Joe Biden” since that would be beneficial to screen reader users.
We can achieve this with a
visually-hidden class in CSS and by applying that class to our element.
Essentially this hides whatever it’s applied to unless it’s a focusable element currently being focused by screen reader controls or the tab key, in which case it is revealed.
Note that if adding to link text to make it more accessible, always append rather than inserting words into the middle of the existing text. That way, you avoid solving an accessibility for one group but creating another for another group (Dragon speech recognition software users).
Visually hidden until focused
There are other CSS approaches to hiding visually. One approach is to not only add
position: absolute (removing the element from the document flow) but also position it off-screen with
left: -100vw or similar. The use case for this approach might be when you want your visually hidden element to support being revealed and for that reveal to occur via a transition/animation from off-screen into the viewport. See Scott O’Hara’s off screen skip-links example.
Hide from Assistive Technologies (such as screen readers)
We sometimes hide visual elements from Assistive Technologies because they are decorative and have accompanying text, for example a “warning” icon with the text “warning” alongside. If we did not intervene then Assistive Technologies would read out “warning” twice which is redundant.
To achieve this we can apply
aria-hidden="true" to our element so that screen readers know to ignore it. In the following examples we hide the SVG icons within buttons and links, safe in the knowledge that the included “Search” text is providing each interactive element with its accessible name.