This page explores the accessibility and impacts of a number of techniques used to hide and minimize content in digital publications.
It is generally advised to avoid including hidden content that is only intended for users of
assistive technologies, however, except where the content is not central to understanding the
publication. Standard hyperlinks to text alternatives and declarative approaches to minimizing
content (e.g., the details
element) are more broadly usable than
hidden content, as not everyone who can benefit from this content uses an assistive technology.
When content has to be selectively made to appear, ensure that progressive enhancement techniques are followed.
Table of Contents
HTML Techniques
-
HTML5 introduced the
hidden
attribute as a way to declaratively hide content (i.e., to hide content without relying on other technologies like CSS). When the attribute is set on an element, its content will not be rendered in any presentation, so will not be read by assistive technologies.The value of attribute has to be either an empty string, as in the previous example, or the value "
hidden
" (hidden="hidden"
). Although referred to as a "boolean" attribute, its value cannot be set to "true" or "false". To make content visible again, thehidden
attribute has to be removed from the element.The
hidden
attribute is most appropriate to author directly on an element when its content will never be made visible. (See the scripting section on dynamically setting the attribute if content will be toggled between visible and hidden states.)The
hidden
attribute is most commonly used with the ARIA attributes that do not require visible content, likearia-labelledby
andaria-describedby
.The effect of setting this attribute is the equivalent of setting the CSS
display
property tonone
. It is more reliable than CSS options in modern user agents, however, as not all user agents support CSS styling.*[hidden] { display: none; }
- The
details
element -
The
details
element does not strictly meet the requirement of hiding content. What it does provide is the ability to collapse content down to just the label specified in thesummary
tag. One advantage of the element is that it does not require scripting support, which is often lacking in EPUB reading systems, to expand and collapse the content.Example — Effect of the
details
elementThe following examples shows a collapsed
details
element. Clicking on the label expands the content.Markup:
<details> <summary>Description</summary> <p>The first of the three gas giants is …</p> </details>
Demo:
Description
The first of the three gas giants is …
It is not required that the content begin in a collapsed state. By adding the
open
attribute, the content will initially be expanded (the attribute is also a boolean, like thehidden
attribute, so its value is either an empty string or the valueopen
).Example — Expanded
details
elementMarkup:
<details open=""> <summary>Description</summary> <p>The first of the three gas giants is …</p> </details>
Demo:
Description
The first of the three gas giants is …
A current limitation, however, is that reading systems do not always repaginate well when the element is expanded or collapsed. Expanding may force content below the element off the bottom of the current page, making it unavailable to sighted readers. The attribute is also not well supported in older browsers, including not at all in Internet Explorer versions, so requires a polyfill to work.
The
details
element is commonly paired with thearia-details
attribute to associate descriptions with elements.
CSS Techniques
Although CSS provides a number of approaches to hiding content visually, the primary problems with using it are that:
- CSS is not always supported and can often be disabled by users.
- Support for new properties often takes a long time to develop and many never get supported in older user agents.
- EPUB reading systems often supply their own styling, so author styles may be ignored or overridden.
As a result, there is no guarantee that styled content will be hidden from any users depending on the user agent they are using. HTML techniques are generally more reliable.
- Setting
display
tonone
-
The
display
property is a widespread method used to visually hide content, as its origins go back much further than thehidden
attribute and it is more direct and easily manipulable than setting the height and width of elements. Setting thedisplay
tonone
causes the element it is carried on to be removed from visual display and the accessibility tree, so assistive technologies will not read the content.Example — Effect of no display
Markup:
.display-none { display: none; } <p>This is the visible text<span class="display-none"> and this is not</span>.</p>
Demo:
This is the visible text and this is not.
Like with the
hidden
attribute, content that is hidden using thedisplay
property can be accessed by ARIA attributes that accept hidden content. The same flaw that this approach hides useful information from users who do not use assistive technologies also applies, however. - Clipping
-
Clipping is a technique that reduces content to a single pixel so that visual users are not aware that that the additional content is present.
The advantage of clipping content instead of hiding it completely is that assistive technologies will read the clipped content, whereas they ignore content set or styled to be hidden.
The
clip-path
property is the primary property used to achieve this effect, but a number of others are also required (some as fallbacks), as depicted in the following example.Example — Effect of clipping
The
span
containing the text "and this is not" will not be visible when the content is rendered, but the text will still be read by an assistive technology.Markup:
.clip { clip-path: inset(100%); clip: rect(1px, 1px, 1px, 1px); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px; } <p>This is the visible text<span class="clip"> and this is not</span>.</p>
Demo:
This is the visible text and this is not.
Note
The
clip
property is now deprecated. It is included as a fallback for older browsers.While this technique works well in web browsers, support in EPUB reading systems is inconsistent. Support for the new
clip-path
property is not widespread, and neither is support for olderclip
property as it requires absolute positioning. - Zero
height
andwidth
-
Setting an element's
height
andwidth
properties to0
is similar to the clipping technique, except that assistive technologies typically will not read the content of elements without any size dimensions.Example — Effect of zero height and width
Markup:
.zero-height-width { height: 0; width: 0; } <p>This is the visible text<span class="zero-height-width"> and this is not</span>.</p>
Demo:
This is the visible text and this is not.
Even though setting an element's dimensions to zero does not remove the content from accessibility tree, assistive technologies are often optimized to ignore content styled this way (it is why the clipping technique only reduces the size to one pixel, for example). This behavior is not universal, however, so the content may be read in some cases.
- Transparent
opacity
-
Setting the
opacity
property of an element to0
makes it completely transparent to users, but assistive technologies will still read the text.Example — Effect of full opacity
In the following example, the second paragraph has its opacity set to
0
to make it transparent, but there is still space where it is located.Markup:
.transparent { opacity: 0; } <p>This paragraph appears.</p> <p class="transparent">While this one is made fully opaque.</p> <p>So there is space between.</p>
Demo:
This paragraph appears.
While this one is made fully opaque.
So there is space between.
The primary issues with the use of
opacity
are support in EPUB reading systems and that it leaves space where the opaque text is.Note
It is also possible to change the opacity of just the text of an element by setting the alpha channel to be transparent (e.g., using the
rgba()
or#RRGGBBAA
value syntax). Support for alpha channel values is also not widespread in EPUB, however. - Transformations
-
The
transform
property provides two options for hiding content: one is to scale the element to zero, and the other is to translate it off screen. In both cases, assistive technologies will still read the text.Using the
scale
transform essentially shrinks the referenced element down until it occupies no space. It is similar in effect to setting the height and width to zero, except that the full space the element would occupy does not disappear when scaling.Example — Effect of scaling
In the following example, the second paragraph is scaled to zero, but the space it occupies remains. Click the button in the demo to toggle the scaling.
Markup:
.scale { transform: scale(0); } <p>This paragraph appears.</p> <p class="scale">While this one is scaled.</p> <p>So there is space between.</p>
Demo:
This paragraph appears.
While this one is scaled.
So there is space between.
Using the
translate
transform is similar in effect to absolute positioning content off screen, except that the full space the element would occupy does not disappear. The value is thex
andy
coordinates of the translating vector.Example — Effect of translating
In the following example, the second paragraph is translated off screen using a an x-coordinate of
-9999px
and y-coordinate of0
. The space the element occupies remains, however. Click the button in the demo to toggle the effect.Markup:
.translate { transform: translate(-9999px); } <p>This paragraph appears.</p> <p class="translate">While this one is translated off screen.</p> <p>So there is space between.</p>
Demo:
This paragraph appears.
While this one is translated off screen.
So there is space between.
Similar to the
opacity
, the primary issues with usingtransform
is that such animations are not well supported in EPUB reading systems and they leave space where the transformed text originated. - Setting
visibility
tohidden
-
The
visibility
property is not commonly used to hide content in digital publications, as unlike thedisplay
property it leaves a space in the rendered content where the element would appear. The content is not read by assistive technologies, despite the visible space.Example — Effect of hidden visibility
In the following example, a space the length of the text " and this is not" occurs where the hidden
span
is. Click the button in the demo to toggle the visibility.Markup:
.vis-hidden { visibility: hidden; } <p>This is the visible text<span class="vis-hidden"> and this is not</span> but now with space.</p>
Demo:
This is the visible text and this is not but now with space.
The property is more commonly used on the Web to avoid the other content on the page shifting around when an element is hidden or made visible (e.g., to prevent a page footer from being pulled up from the bottom of the page).
Similar to the
display
property, content hidden this way is hidden to assistive technologies unless it is referenced from an ARIA attribute that allows hidden content. - Absolute
position
-
Absolute positioning content off-screen using the
position
property is another common Web practice to hide it visually while leaving it for assistive technologies to announce. As it is only the visual position of the content that changes, assistive technologies will still read the text.Example — Effect of absolute positioning
Markup:
.abs-position { position: absolute; left: -9999px; } <p>This paragraph appears.</p> <p class="abs-position">While this one is positioned off screen.</p> <p>But there is no space between.</p>
Demo:
This paragraph appears.
While this one is positioned off screen.
But there is no space between.
Using absolute positioning to place content off-screen is very unreliable in EPUB reading systems, however. Absolute positioning of content is often disabled outside of fixed layout publications, as it complicates the rendering and paginating of reflowable content. As a result, the content may appear fixed in an unexpected position on the page, potentially obscuring the other content for visual readers.
- Negative
text-indent
-
The
text-indent
property is sometimes used to push content out of the visible area of the screen by giving it a large negative number. Using a large number allows the text to be rendered on a single line and not reach the visible area of the screen. The content is still read by assistive technologies, even though it is not visually present.Example — Effect of negative indenting
In the following example, the negative indent on the second paragraph forces it to be rendered off-screen, giving the appearance it is no longer there. Click the button in the demo to toggle the indent.
Markup:
.negative-indent { text-indent: -9999px; } <p>This paragraph appears.</p> <p class="negative-indent">While this one is pushed off screen.</p> <p>But the space the element occupied remains.</p>
Demo:
This paragraph appears.
While this one is pushed off screen.
But the space the element occupied remains.
Even among CSS techniques, negative indents tends to be particularly unreliable. It has been noted that it can cause a large scrollbar to appear in browsers, for example, to allow users to reach the content (although this can be mitigated by setting the directionality). The more common issue with EPUB reading systems is that they ignore negative indents and other attempts to manipulate content outside the viewing area.
It also normally requires other tandem properties, like shrunken font sizes or changes to the element height, to collapse the white space that results from simply moving the first line back. These may not be well-supported in EPUB reading systems, either.
Note
A similar technique employing an indent of
100%
to push the code off-screen in the other direction has also been suggested for browsers, but this will also fail in reading systems that prevent content from being positioned off-screen. - Matching
color
with background -
Although it is possible to hide content by making the foreground color match the background, it is arguably the worst option available for EPUB content.
The problems with hiding content this way in EPUB include:
- Reading systems often apply their own foreground and background colors so that all publications have the same look and feel. As a result, there is no guarantee the text will actually be hidden.
- Similarly, reading systems often provide users the option to change their color preference for foreground and background text.
- Reading systems often offer multiple reading modes (e.g., night reading) that reset the foreground and background colors, which will reveal the text even if it is hidden by default.
A more common problem across any user agent is that this method of hiding only obscures the text. Like with changing the visibility, the area the text occupies is still visible.
Assistive technologies will read text hidden this way, though, as changing the color does not actually remove it.
Example — Effect of matching text with background
In the following example, both the
color
andbackground-color
properties are set to white to obscure the text.Markup:
.color-match { color: rgb(255,255,255); background-color: rgb(255,255,255); } <p>This paragraph appears.</p> <p class="color-match">While this one is colored to be hidden.</p> <p>So there is space between.</p>
Demo:
This paragraph appears.
While this one colored to be hidden.
So there is space between.
ARIA Techniques
Although ARIA does not influence the display of content, it contains a number of attributes that can be used both to hide content from, and make hidden content accessible to, assistive technologies.
- The
aria-describedby
attribute -
The
aria-describedby
attribute is commonly used to associate hidden descriptions with an element, although it is not required that the referenced element be hidden. The value of the attribute is the ID of the element that contains the description.Example — Associating a desciption with an image
Note that the value of the attribute is not a fragment identifier (i.e., it does not include a hash character (
#
) at the start, as would be expected in a hyperlink).<img … aria-describedby="img-desc"/> <p id="img-desc" hidden="hidden">The infographic shows …</p>
The
aria-describedby
attribute may reference more than one element if the description is broken up across elements.The problem with using
aria-describedby
to reference any content, hidden or not, is that it reduces that content to a simple text string (i.e., there is no way to effectively move through the description). Users of assistive technologies consequently have to listen to that entire string of text before they can move on, which can be a frustrating experience.The use of
aria-describedby
with hidden content also limits access to the description to users of assistive technologies when there will be many users who could benefit from access. - The
aria-details
attribute -
The
aria-details
attribute is similar to thearia-describedby
attribute in that both identify additional information about the content of an element, but there are a couple of key differences:- It is not intended to reference hidden content.
- It does not reduce the referenced content to a simple text string — users are able to navigate the structure of the referenced content.
The value of the
aria-details
attribute is the ID of the element that contains the description. The attribute can reference only a single element.The attribute is commonly used to reference the collapsible
details
element. This use makes it one of the best options for providing descriptions in as minimally obtrusive a manner as possible for all users.Note
The use of "details" in the element and attribute names is somewhat coincidental. The
aria-details
element can refer to any element containing additional information.Example — Adding a description for an image
Note that the value of the attribute is not a fragment identifier (i.e., it does not include a hash character (
#
) at the start, as would be expected in a hyperlink).<img src="dollars.jpg" alt="…" aria-details="dollar-desc"/> <details id="dollar-desc"> <summary>Description</summary> … </details>
-
Despite its name, the
aria-hidden
attribute does not control the visual rendering of content. When set, it indicates that the designated content is not to be rendered by an assistive technology (i.e., it is not to be included in the accessibility tree).Unlike the
hidden
attribute, the value must be "true
" or "false
". An empty value (aria-hidden=""
) is the same as not specifying the attribute.The
aria-hidden
attribute should rarely be needed in digital publications. It is only of use if there is redundant or extraneous visual content, like pull quotes.Note that ARIA attributes that can reference hidden content (e.g.,
aria-describedby
andaria-labelledby
) ignore this attribute — they will include the hidden text in their values. - The
aria-label
andaria-labelledby
attributes -
The
aria-label
andaria-labelledby
attribute both allow an accessible name to be provided for an element.aria-label
allows a hidden name to be specified.Example — Specifying a hidden name
<section aria-label="Explanation">
The attribute is useful in digital publishing where only whitespace has been used to indicate new sections (e.g., headingless front matter sections, groups of index or bibliography entries). It is important that these sections be given a name, as without an explicit heading a
section
will not be navigable by assistive technology.The
aria-labelledby
attribute serves an identical purpose, but it allows the name to be included in another element (which can be hidden). The value of thearia-labelledby
attribute is the ID of the element that contains the name.Example — Specifying an visible name
Note that the value of the attribute is not a fragment identifier (i.e., it does not include a hash character (
#
) at the start, as would be expected in a hyperlink).<div role="note" aria-labelledby="note-hd"> <p id="note-hd" class="hd">Warning!</p> … </div>
The
aria-labelledby
attribute may reference more than one element if the label is split across multiple elements.It is not strictly necessary to use the
aria-labelledby
attribute when a section of content has an explicit heading.Example — Section with explicit heading
<section> <h2>Definitions</h2> … </section>
Assistive technologies will associate the first heading element with the section. It can help with older browsers and assistive technologies to explicitly associate headings, however.
- The
presentation
role -
A common misconception is that adding the
presentation
role to an element is a way to hide content from assistive technologies. It is not!This misconception arises in part because this role is often applied to images that users do not need to encounter.
Example — Image used for visual spacing
<img src="spacer.href" alt="" role="presentation"/>
In fact, it is the empty
alt
attribute that signals to assistive technologies that there is no content and the image can be safely ignored.Setting
role="presentation"
on any element only removes its semantics. The content of the element is untouched.Note
The ARIA working group is moving to replace the
presentation
role withnone
to better reflect that it is the semantics of the element that are ignored, not the content.
Scripting Techniques
Although JavaScript does not provide any new abilities of its own to hide content, it allows
developers to manipulate a document to hide content using all of the techniques mentioned on this
page. Developers can dynamically add and remove the hidden
attribute, for example, or
assign CSS classes to elements. And ARIA, of course, is designed to be modified by script.
Example — Setting attributes and classes
The following example shows how the hidden
attribute can be added to an element
using the JavaScript setAttribute
function and the class hide
can
be added using classList.add
.
/* set the hidden attribute */
document.getElementById('hideyho').setAttribute('hidden','');
/* set a css class */
document.getElementById('hideyho').classList.add('hide');
The one advantage that JavaScript has over using native techniques directly is that it allows for progressive enhancement when hiding content. There are times when content may need to be toggled on and off depending on user preference.
For example, a book on programming might include examples in multiple languages, allowing the user to selectively enable only the language they are most comfortable with. Using HTML or CSS techniques to hide one language by default could lead to those examples never being available to a user without scripting support (i.e., the scripts to toggle the choice will not work). By instead using JavaScript when the page loads, nothing will be hidden from users if scripting is not available; the scripting fails gracefully without loss of information.
Similarly, if the answers to questions in a textbook are only revealed using script, they will not be accessible to any users.
Example — Progressive enhancement
The following example uses the details
element to hide the answer in reading
systems that do not support scripting. When scripting is supported, the details
element is hidden and a set of radio buttons are enabled instead, with a message about
whether the answer is correct or not being dynamically generated.
There are buttons after the demo to reset the question and toggle between the dynamic and static versions.
Markup:
<fieldset>
<label>Which of the following is a liquid?</label>
<ul class="q">
<li>
<input type="radio" name="q1-ans" value="a"
onclick="revealResult(true)" hidden="hidden">
A - Water
</li>
<li>
<input type="radio" name="q1-ans" value="b"
onclick="revealResult(false)" hidden="hidden">
B - Ice
</li>
<li>
<input type="radio" name="q1-ans" value="c"
onclick="revealResult(false)" hidden="hidden">
C - Steam
</li>
</ul>
<div id="q1-result" aria-live="assertive" hidden=""></div>
<details id="q1-static-ans">
<summary>Answer</summary>
<p>A - Water</p>
</details>
</fieldset>
<script>
document.onload = configureTest();
function configureTest() {
document.getElementById('q1-static-ans').classList.add('hidden');
document.getElementById('q1-result').removeAttribute('hidden');
var q1_ans = document.getElementsByName('q1-ans');
q1_ans.forEach( function(checkbox) {
checkbox.removeAttribute('hidden');
});
}
function revealResult(correct) {
var res_elem = document.getElementById('q1-result');
var result = correct ? 'Correct!' : 'Sorry, try again!';
res_elem.textContent = '';
res_elem.appendChild(document.createTextNode(result));
}
</script>
Demo:
Related Links
- MDN — <details>: The Details disclosure element
- MDN — hidden
- HTML — The
hidden
attribute - HTML — The
details
element - WCAG 2.1 — Using CSS to hide a portion of the link text
- CSS — Clipping Shape: the clip-path property
- CSS — Content height: the 'height' property
- CSS — Content width: the 'width' property
- CSS — The 'display' property
- CSS — Visibility: the 'visibility' property
- CSS — Indentation: the 'text-indent' property
- CSS — Choosing a positioning scheme: 'position' property
- CSS — Transparency: the 'opacity' property
- CSS — The 'transform' Property
- CSS — Foreground color: the 'color' property
- ARIA — aria-hidden (state)
- ARIA — aria-describedby (property)
- ARIA — aria-details (property)
- ARIA — aria-label (property)
- ARIA — aria-labelledby (property)
- ARIA — presentation (role)