23

If I have lots of DOM on the page and I set them all to display: none, the browser still reacts quickly (scrolling is fast, page feels snappy).

However, if I visibility: hidden the elements, the browser is as slow as if they were all drawn on the screen.

Can someone explain, in detail, why this is the case?

Knu
  • 14,806
  • 5
  • 56
  • 89
Joda Maki
  • 5,649
  • 6
  • 27
  • 36
  • possible duplicate of [Does opacity:0 have exactly the same effect as visibility:hidden](http://stackoverflow.com/questions/272360/does-opacity0-have-exactly-the-same-effect-as-visibilityhidden) – givanse Dec 16 '13 at 19:13

9 Answers9

27

Well in a way, they are drawn (but not really): The browser keeps space for them, so it must consider the items when laying out the visible ones.

See MDC visibility:hidden:

The box is invisible (fully transparent, nothing is drawn), but still affects layout. Descendants of the element will be visible if they have visibility:visible (this doesn't work in IE up to version 7).

If you specify display: none instead, the browser only as to care about and layout the visible ones. It does not have to take the others into account at all.

Depending on your visible/invisible ratio and the number of elements, this can make a difference.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
14

Imagine a painting.
You have a white background and start drawing an apple with a lot of details during one hour and then you completely cover it with another coat of white paint. That's visibility.

display:none is like not drawing it from the start. Of course it's faster on first load.

There are drawbacks when you are using display:none though: when you are switching it back to block (or inline etc) you will have to start drawing the painting but using visibility the browser is just scratching the last coat of paint and it's back. So visibility is faster in this case.

But remember one thing when you are using visibility:hidden the element retains its position in the flow so the elements around it won't budge.

If you want a technical explanation check David Baron's talk.

Knu
  • 14,806
  • 5
  • 56
  • 89
4

This is quite interesting. So in essence visibility: hidden is technically the same as opacity: 0?

I'm no browser maker, but wouldn't it be a huge performance gain if elements that have visibility hidden weren't rendered or painted but instead painted as a transparent square with the dimensions of the element? At least in situations where the dimensions were known.

Erik Veland
  • 737
  • 1
  • 7
  • 11
3

With visibility:hidden they are all drawn on the screen, but they are not visible by the user. Instead, with display:none they aren't drawn

stecb
  • 14,478
  • 2
  • 50
  • 68
  • 1
    I would clarify, for `visibility:hidden` they are rendered in the layout but **not** drawn on the screen. – jball Jan 17 '11 at 22:00
2

With visibility: hidden their sizes have to be computed so the appropriate amount of space can be reserved for them. They are, effectively, still drawn.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

Because display: none actually removes the elements from the DOM. visibility: hidden merely makes them invisible, but they're still there.

You can notice the difference because form input fields that have display: none will simply not be included in the form when you submit it; input fields that merely have visibility: hidden set will still be there. Well, at least, that's my experience -- other browsers may behave differently.

bart
  • 7,640
  • 3
  • 33
  • 40
  • 1
    Styles should not be affecting the DOM. The behaviour described here contradicts section "17.13.2 Successful controls" in the HTML 4.01 spec. – CurtainDog Jan 18 '11 at 00:01
  • 5
    display: none; does not remove or in anyway affect an element's DOM representation. – csuwldcat Jan 24 '13 at 16:43
  • 3
    I have verified that for some browsers, setting `display: none` dynamically *does* remove the elements from the DOM, regardless of what the spec says. That is apparently a performance optimization. I have seen it at least in Safari 6.2.2. Upvote parent. – Yitz Jan 20 '15 at 11:16
1

display: none: element will not be included in render tree

visibility: hidden: element will be included in render tree (and layout process) but won't be painted in the end thus it is computationally more expensive.

Mechanic
  • 5,015
  • 4
  • 15
  • 38
0

"the browser is as slow as if they were all drawn on the screen."

I think this is slow because the tag is still rendered, but isn't seen on the screen.

Check out this

Community
  • 1
  • 1
VoodooChild
  • 9,776
  • 8
  • 66
  • 99
0

Using display:none, the browser does not initialize these elements nor render the content. This is not the case when using visibility:hidden, which initializes these elements but just hides them.

http://wiw.org/~frb/css-docs/display/display.html

Evan Mulawski
  • 54,662
  • 15
  • 117
  • 144