155

HTML5 has a new global attribute, hidden, which can be used to hide content.

<article hidden>
   <h2>Article #1</h2>
   <p>Lorem ipsum ...</p>
</article>

CSS has the display:none rule, which can also be used to hide content.

article { display:none; }

Visually, they are identical. What is the difference semantically? Computationally?

What guidelines should I consider on when to use one or the other?

TIA.

EDIT: Based on @newtron's responses (below), I did more searching. The hidden attribute was hotly contested last year and (apparently) barely made it into the HTML5 spec. Some argued it was redundant and had no purpose. From what I can tell, the final evaluation is this: If I'm targeting only web browsers, there is no difference. (One page even asserted that web browsers used display:none to implement the hidden attribute.) But if I'm considering accessibility (e.g., perhaps I expect my content to be read by screen-readers), then there is a difference. The CSS rule display:none might hide my content from web browsers, but a corresponding aria rule (e.g., aria-hidden="false") might try to read it. Thus, I now agree that @newtron's answer is correct, though perhaps (arguably) not as clear as I might like. Thanks @newtron for your help.

james.garriss
  • 12,959
  • 7
  • 83
  • 96
  • For those who haven't yet had the joy of reading the HTML5 spec on this attribute: http://www.w3.org/TR/html5/editing.html#the-hidden-attribute – james.garriss Jul 15 '11 at 14:17

3 Answers3

82

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.

newtron
  • 5,938
  • 1
  • 23
  • 19
  • 1
    So you're saying that hidden trumps display? If so, then you are saying that it's purpose is simply to override the presentation. Hmmm. – james.garriss Jul 15 '11 at 14:21
  • 1
    my guess is that, yes, hidden trumps display. but, i haven't actually experimented with it. it would seem rather pointless if the css could override it. – newtron Jul 15 '11 at 14:23
  • 1
    You might well be right, but I'm not sure that you've answered the question. Perhaps if I rephrase my question like this: I have content on my page that I want to visually hide. I could use hidden or display:none. How do I choose between the two? – james.garriss Jul 15 '11 at 14:26
  • 1
    you choose by determining whether it's something that should be hidden to everyone, regardless of how they are viewing the page (device, browser, screen size, etc). if it should be hidden from everybody in all contexts, use `hidden`. if it should only be hidden for specific browsing scenarios, use `display: none` (or, `visibility: hidden` maybe). – newtron Jul 15 '11 at 14:29
  • 3
    Semantics win. If it shouldn't be there then remove it from the doc flow at the doc level. If it should be a part of the doc flow but in certaain cases you don't want it to be a part of the visual experience then handle it at the cosmetic layer. Bear in mind that some agents attempt to parse CSS and if they determine that something wouldn't be SEEN then they don't output it at all. I think this is aberrant behavior but it can help to know. –  Jul 15 '11 at 18:57
  • Does "cosmetic layer" = CSS? If so, then you are not always correct. Go read this section in the HTML5 spec. Link above. If it != CSS, then what does it mean? – james.garriss Jul 18 '11 at 00:31
  • display trumps hidden! – Jeroen Versteeg Jun 21 '13 at 07:23
  • if 'hidden' shouldn't be used to hide something that 'could' be displayed, why the f would you use it? an intelligent application would omit the element from render! – pstanton Nov 19 '14 at 18:47
  • I haven't yet seen any discussion on robots/crawlers/SEO. I wonder, does the `hidden` attribute hide the content from search engines, microdata parsers, etc? If that's the case, then this would imply that the `hidden` attribute is more than simply a cosmetic effect—it has semantic value (as all attributes should). Maybe setting `display: block;` shouldn't "unhide" a hidden element. – chharvey Dec 15 '15 at 16:25
  • 10
    Related to some of the comments here (@james-garris, @newtron), according to https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden, display actually trumps hidden - go figure:-) – Jurko Gospodnetić Jul 08 '16 at 06:53
  • 4
    One important difference I spotted on MDN page for hidden attribute: "Changing the value of the CSS display property on an element with the hidden attribute overrides the behavior. For instance, elements styled display: flex will be displayed despite the hidden attribute's presence." – mohsinulhaq Jul 16 '19 at 08:30
  • This isn't really an aspect of `display: none`, but rather of whether you use media queries. If it is shown based on a media query, then it's not really a case of `display: none`, then, is it? – TylerH Jan 20 '23 at 17:22
21

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:

  1. Use hidden for a "thank you" message that should not exist as part of the page until a form has been filled in.

  2. 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.

  3. Use display: none for navigation that is only shown when a user hovers or clicks a menu button.

  4. 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).

  5. 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.

Andrew Parks
  • 6,358
  • 2
  • 12
  • 27
8

What is the difference between the hidden attribute (HTML5) and the display:none rule (CSS)?

MDN confirms that:

Changing the value of the CSS display property on an element with the hidden 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:

  • a) <p hidden>
  • b) <p class="hidden"> where .hidden {display: none;}

So... hidden and class="hidden" are interchangeable, right?

Wrong.


Adding Accessibility:

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:

  • b) <p class="hidden" aria-hidden="true"> where .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.

  1. display: none;
  2. visibility: hidden; (don't show, but still hold the space)
  3. opacity: 0;
  4. width: 0; height: 0;
  5. aria-hidden="true"
  6. and in the case of form data, input type="hidden"

Source: https://davidwalsh.name/html5-hidden#comment-501242

Rounin
  • 27,134
  • 9
  • 83
  • 108
  • 1
    Accessibility devices such as screen readers would benefit from understanding the difference between content existing yet not currently displayed (to prevent clutter), and content marked as `hidden` and not currently part of the content of the page. – Andrew Parks Nov 02 '20 at 11:01
  • Yes, that's a good point, @AndrewParks... but then I suppose `hidden` ends up being a shorter (and possibly less intuitive?) way to convey: `class="hidden" aria-hidden="true"`. See [What's the difference between HTML 'hidden' and 'aria-hidden' attributes?](https://stackoverflow.com/questions/31107040/whats-the-difference-between-html-hidden-and-aria-hidden-attributes) and [Using the aria-hidden attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute) – Rounin Nov 02 '20 at 11:10