CSS Properties: Display vs. Visibility

What is difference between Display vs. Visibility properties?


Solution 1:

The visibility property only tells the browser whether to show an element or not. It's either visible (visible - you can see it), or invisible (hidden - you can't see it).

The display property tells the browser how to draw and show an element, if at all - whether it should be displayed as an inline element (i.e. it flows with text and other inline elements) or a block-level element (i.e. it has height and width properties that you can set, it's floatable, etc), or an inline-block (i.e. it acts like a block box but is laid inline instead) and some others (list-item, table, table-row, table-cell, flex, etc).

When you set an element to display: block but also set visibility: hidden, the browser still treats it as a block element, except you just don't see it. Kind of like how you stack a red box on top of an invisible box: the red box looks like it's floating in mid-air when in reality it's sitting on top of a physical box that you can't see.

In other words, this means elements with display that isn't none will still affect the flow of elements in a page, regardless of whether they are visible or not. Boxes surrounding an element with display: none will behave as if that element was never there (although it remains in the DOM).

Solution 2:

visibility: hidden;

  • the element won't be painted AND don't recieve click/touch events, but the space it takes is still occupied
  • because it's still there for layout purposes, you can measure it without it being visible
  • changing content will still cost time reflow/layouting the page
  • visibility is inherited, so this means you can make subchildren visible by giving them visibility: visible;

display: none;

  • will make the element not participate in the flow/layout
  • can (depending on the used browser) kill Flash movies and iframes (which will restart/reload upon showing again), although you can prevent this from happening with iframes
  • the element won't take up any space. for layout purposes it's like it does not exist
  • will make some browsers/devices (like the iPad) directly take back memory used by that element, causing small hickups if you switch between none and an other value during animations

extra notes:

  • images in hidden content: in all popular browsers images are still loaded, even though they are within any element with visibility: hidden; or display: none;
  • fonts in hidden content: webkit browsers (Chrome/Safari) may delay loading custom fonts which is only used in hidden elements, including through visibility or display. This may cause you to measure elements which are still using a fallback font until the custom font is loaded.

Solution 3:

display: none removes the element out of the flow of the html whereas visibility:hidden does not.

Solution 4:

display:none; will remove the DOM elements visual style / physical space from the DOM, whereas visibility:hidden; will not remove the element, but simply hide it. So a div occupying 300px of vertical space in your DOM will STILL occupy 300px of vertical width when set to visibility:hidden; but when set to display:none; it's visual styles and the space it occupies are hidden and the space is then "freed" up for lack of a better word.

[EDIT] - It was a while back that I wrote the above, and whether I was not knowledgeable enough or having a bad day, I don't know, but the reality is, the element is NEVER removed from the DOM hierarchy. All block level display 'styles' are completely 'hidden' when using display:none, whereas with visibility:hidden; the element itself is hidden but it still occupies a visual space in the DOM. I hope this clears things up