In this article we will see what happens to the layout model of HTML elements when you use this particular CSS declaration.

The CSS display property allows us to specify a layout model for HTML elements. When you declare a layout model, browsers internally select a specific algorithm that will be applied to the final rendering of HTML elements.

When we declare display: none, we're actually performing an hard reset of the default layout model of a given element. The most important consequence of this from a pure JavaScript point of view is that computed dimensions are completely zeroed, especially heights.

Suppose that we want to show a modal overlay on a page. We can create the following HTML structure.

    <main id="site"></main>
    <div id="overlay"></div>

Now when we show the overlay we want to hide the main site's container with display: none. Our overlay should have an height that is equal to the overall height of the viewport. We can write the following CSS code:

#overlay {
    width: 100%;
    min-height: 100vh;
    position: absoute;
    top: 0;
    left: 0;
    z-index: 100000;
    background-color: #fff;
    display: none;

This is the simplest scenario that we can handle. When the overlay switches from none to block, browsers see the min-height: 100vh declaration, which is applicable to a block layout model, and automatically adjust the element's computed height to the desired value. So far so good.

But what happens to #site? Simply put, now its computed height is zero. In this case this is not a problem, because we don't need to take it into account when we want to display our overlay element.

The question is: what is the actual computed height of the document object when we apply display: none to an element? The answer is simple: it's given by the computed height of all elements that still have a display value othen than none minus the original computed height of all elements that now have the declaration display: none.

In our example, the computed height of the document object is zero. As we said earlier, this is not a problem because our overlay element has a declaration of min-height: 100vh and there are no more top level elements on that page.

Problems arise when our overlay element must have a dynamic height calculated via JavaScript. In this case we can't simply assign a static minimum height but we actually need to specify an height that equals the original document computed height.

The solution is to save the original computed height before our hide/show logic (see the MDN reference page).

'use strict';

const originalHeight = document.body.clientHeight;
const overlay = document.querySelector('#overlay');
const site = document.querySelector('#site'); = 'none'; = originalHeight + 'px'; = 'block';

Two more questions:

  1. Why did we choose absolute instead of fixed?
  2. Why did we choose min-height instead of height?

The answer is simple: the overflow property. When we have some predetermined content, such as a single image or video with fixed dimensions, it doesn't matter which positiong or height algorithm you choose.

But when you have some dynamic content with variable heights, such as a list of blog posts, choosing a fixed height algorithm will force the browser to decide whether to show or not a scrolling mechanism. This is particularly evident on mobile devices, when you'll get the unwanted side effect of having a portion of your contents which is not visible due to the fact that the page scrolling stops at the very bottom of the document.