Accessibility and Hiding Content with HTML and CSS
February 17, 2000
//import HiddenContentWidget from â./HiddenContentWidgetâ;
Conditionally hiding and showing content is a common practice in websites with rich interactions. There are a few ways to toggle presentation on the page and itâs important to understand how each works and what side effects they have, especially with respect to how assistive technologies interpret hidden content.
To demonstrate, letâs take a look at a simple link component.
Here is some <a href="#" id="link-to-hide">hidden</a> content.
Here is some hidden content.
The Basics of Hiding Content
There are quite a few methods for hiding an HTML element, many of which are rooted in manipulating CSS properties. Letâs focus on a few of those properties and what they default to by examining our âhiddenâ link.
Letâs hop into the browserâs developer tools (cmd+option+I
on Mac, ctrl+shift+I
on Windows) and use the console to find out some information about the âhiddenâ link while itâs still visible.
We can access our link with document.querySelector("#link-to-hide")
. Letâs assign it to a variable so we can continue to gather information.
const link = document.querySelector('link-to-hide')
Now letâs look at the style of our link.
const style = window.getComputedStyle(link)
This gives us a CSSStyleDeclaration
object that looks unweildy if we print it out raw, but is powerful if we know what weâre looking for.
display
Letâs take a look at our linkâs display
property. display
controls the display type (e.g. block
or inline
) of our element and the layout its children are displayed in (e.g. flow
, grid
, flex
, or even table
). The value that would hide our element is none
, but weâll save that for later.
style.display //outputs "inline"
The default value here is inline
, meaning our element does not generate line breaks before or after itself and is not hidden by default.
opacity
Now letâs look at our linkâs opacity. Opacity values run from 0
(totally transparent) to 1
(totally opaque). An opacity
value less than 1 places the element in a new stacking context, which is a three-dimensional conceptualization of HTML elements along the z-axis, towards the user. Stacking context can be manipulated a number of ways, but most directly through the z-index
CSS property.
style.opacity //outputs "1"
The default value here is 1
, meaning our element is completely opaque by default.
visibility
Visibility has three possible values: visible
, hidden
, and collapsed
. Iâd hazard a guess that our element defaults to visible
.
style.visibility //outputs "visible"
Getting Fancy
Beyond changing
Weâll conditionally hide it when we press a button. Try it!
//
Visually we can see the button disappear from the page and no space is reserved for the button when itâs hidden. You can no longer click the link or tab to it using your keyboard. The sentence reads âHere is some content.â But what does the DOM tree look like? If you inspect the element using developer tools by right clicking and selecting âinspectâ from the menu
There are two important questions you should ask yourself when hiding content in order to determine the most effective method to use:
1. Should the element still be present in the DOM tree?
Should this element still appear in the HTML markdown? Should it still be interactive even though it isnât visually shown?
2. Should the element be present in the accessibility tree?
The accessibility tree is a subset of the DOM tree that contains metadata about each of its elements so that assisive technology can use accessibility APIs to accurately describe what is on the page. I highly recommend reading this article by Hidde de Vries, which goes into detail about how it works and why itâs important in a really approachable way. The accessibility tree ignores non-semantic elements like wrapper div
s and spans
Letâs look at the example above and see if we can answer those two questions.
Letâs go through some techniques for hiding content and test how they affect the DOM tree and accessibility tree.
Weâll take a link and apply each technique and examine whatâs happening in your browser. Weâll be using the Accessibility
tab in Chromeâs developer tools (open using cmd + option + I
).
visibility: hidden
- visible link
- link
If you inspect the second link above, youâll see that it still shows up in the DOM tree but that you canât tab to it or interact with it. Youâll also notice that the space it would normally take is not saved. It is removed from the accessibility tree.
display: none
- visible link
- link
If you inspect the second link above, youâll see that it still shows up in the DOM tree but that you canât tab to it or interact with it. Youâll also notice that the space it would normally take is not saved. It is removed from the accessibility tree.