HTML5 has a new global attribute, hidden
, which can be used to hide content.
Simple rule:
Are you hiding something because it's not yet semantically part of the page content, like a series of potential error messages that have not been triggered yet? Use hidden
.
Are you hiding something that is part of the page content, such as toggling a paragraph into a collapsed state to avoid clutter? Use display:none
.
hidden
is about semantics (whether something is currently part of the page content) and display: none
is about presentation of the page content.
Unfortunately, hidden
will NOT override any display
CSS, even though it would make intuitive sense that something that is not part of the page should never be displayed. If you want hidden
to be respected, add this css rule: [hidden] { display: none !important }
Examples:
Use hidden
for a "thank you" message that should not exist as part of the page until a form has been filled in.
Use hidden
for a series of potential error messages that could be shown to the user depending on their actions on the page. These errors are not semantically part of the page content until an error has occurred.
Use display: none
for navigation that is only shown when a user hovers or clicks a menu button.
Use display: none
for tabbed panes, where the only reason for the tabbed panes is that it would be too overwhelming to show the user all of the panes simultaneously. (Perhaps if a user had a wide enough screen, all panes would be shown. Therefore the panes were always part of the content of the page, and so CSS presentation logic is the appropriate choice).
Use display: none
to collapse a paragraph or section inside a document. This indicates the paragraph is still part of the page content, but we've hidden it for convenience to the user.
Note: Accessibility devices would benefit from knowing the difference between navigation or content that is present but not currently displayed, vs content that is not currently considered to be part of the page and that should therefore never be described to the user.
What is the difference between the
hidden
attribute (HTML5) and thedisplay:none
rule (CSS)?
MDN confirms that:
Changing the value of the CSS
display
property on an element with thehidden
attribute overrides the behavior.
And we can show this straightforwardly:
.hidden {
display:none;
}
.not-hidden {
display: block
}
<p hidden>Paragraph 1: This content is not relevant to this page right now, so should not be seen. Nothing to see here. Nada.</p>
<p class="hidden">Paragraph 2: This content is not relevant to this page right now, so should not be seen. Nothing to see here. Nada.</p>
<p hidden class="not-hidden">Paragraph 3: This content is not relevant to this page right now, so should not be seen. Nothing to see here. Nada.</p>
<p class="hidden not-hidden">Paragraph 4: This content is not relevant to this page right now, so should not be seen. Nothing to see here. Nada.</p>
This reveals that there is zero presentational difference between:
<p hidden>
<p class="hidden"> // .hidden {display: none;}
Adding Accessibility:
However... there's more to consider than visual presentation. We should also all be catering to screen-readers to maximise accessibility (right?), so the second option immediately above should, more properly, look like this:
<p class="hidden" aria-hidden="true"> // .hidden {display: none;}
Why is using a class="hidden"
and aria-hidden="true"
better than using hidden
?
Because we know that CSS can be over-ridden using either the cascade or specificity and we know that aria-hidden
speaks to accessibility user-agents like screen-readers.
By contrast, the HTML5 hidden
attribute is much sketchier. It doesn't say explicitly what it does or doesn't do - and, worse, it appears to suggest it does things it actually doesn't.
See: https://meowni.ca/hidden.is.a.lie.html
Final Note:
Whatever combination of HTML, CSS and ARIA you go with, note that:
We already have 6 methods for hiding content with different purposes/intentions.
display: none;
visibility: hidden;
(don't show, but still hold the space)opacity: 0;
width: 0; height: 0;
aria-hidden="true"
- and in the case of form data,
input type="hidden"
Source: https://davidwalsh.name/html5-hidden#comment-501242
The key difference seems to be that hidden
elements are always hidden regardless of the presentation:
The hidden attribute must not be used to hide content that could legitimately be shown in another presentation. For example, it is incorrect to use hidden to hide panels in a tabbed dialog, because the tabbed interface is merely a kind of overflow presentation — one could equally well just show all the form controls in one big page with a scrollbar. It is similarly incorrect to use this attribute to hide content just from one presentation — if something is marked hidden, it is hidden from all presentations, including, for instance, screen readers.
http://dev.w3.org/html5/spec/Overview.html#the-hidden-attribute
Since CSS can target different media/presentation types, display: none
will be dependent on a given presentation. E.g. some elements might have display: none
when viewed in a desktop browser, but not a mobile browser. Or, be hidden visually but still available to a screen-reader.