Some Technical Background

If you set an element’s height with a percentage value you have to ask yourself, “A percentage of WHAT?” If an element’s height is 50% what is this 50% value based on? The answer is simple: height percent values are based on the height of the element’s containing block. For example, if I set the height of a UL element to 500 pixels and set the height of a child LI element to 10%, that LI will have a height of 50 pixels. The UL is the containing block of the LI.

But if the containing block has no explicit height set, what happens then? Long story short, that percentage value is treated as auto. You can read all about this in the CSS spec.

Some Design Background

There’s a visual element web designers have been using for years now using different techniques. That is making the layout appear as tall as the viewport even if the content of the page is not tall enough in and of itself to force the layout to that height. Something like this.

My Attempts

The BODY element has a gray background and a DIV with a min-height value set to 100%. This is the trick I use. If I didn’t use min-height, but just regular height then the white box would only be as tall as the viewport and the text would overflow below the white box like this.

So what if I try to nest DIVs with min-height set to 100%? Well then this happens.

The gray box doesn’t go the full height of the screen. Why?

To The Spec!

Take a look at what the CSS spec has to say on min/max-height, specifically this bit about percentage values:

Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box’s containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the percentage value is treated as ‘0’ (for ‘min-height’) or ‘none’ (for ‘max-height’).

So unless the height of the containing block is explicitly set to a value that doesn’t depend on the height of its content min-height takes a value of 0.

The containing block in my example has a min-height value of 100%. The height of this box depends on the height of its content. That’s because if there’s a lot of content the height will be larger than the minimum height of 100%. The height of the containing block is not set in stone. This is why any child element’s min-height value will be treated as 0.

Thus, the gray box does not extend down to the bottom of the page.


So why is it that if I set a height value of 100% on the BODY and HTML elements the gray background color for the BODY doesn’t end like it does to the DIV with the white background color and a height of 100% in this example?

Actually, it does.

BODY Is Special

The BODY element has a fixed height. It inherits this height from the HTML element which inherits it from the viewport of your web browser. If your web page has content that requires more vertical space than is available, the BODY element’s overflow property dictates what happens. In this instance the default vaule for the BODY’s overflow property is auto. This means scrollbars will be generated as needed so that we can scroll through that content inside the BODY element.

This is an important concept here: even though the contents of the BODY element are taller the height of the BODY element itself will only be as tall as the viewport allows. Put it another way, if your browser window is 500 pixels tall then your BODY element is 500 pixels tall. If the content of the BODY element is 1000 pixels tall, the BODY element’s height is still 500 pixels, but scrollbars are generated that let you scroll through the content of the BODY element 500 pixels at a time.

If I set overflow:auto on that white box while it has a height of 100% you’ll see exatly the same thing that’s happening to the BODY in that scrollbars are generated to let you scroll through the content inside the white box.

This is why in this example the white box is only as tall as the window and not as tall as the content. The white box has a height of 100%, but the overflow property of that box takes the default value visible, which means the browser renders all of the content even if it extends beyond the dimensions of the containing block.

Putting It All Together

In my original example both the HTML and BODY elements have a height of 100%. The white box has a min-height of 100%. Using the rule put down by the CSS spec we can see that the containing block of the white box (the BODY element) has an explicit height (the height of the viewport) and that height value does not rely on the content of its children (it relies on the dimensions of the viewport). Thus the white box will have a minimum height the same as the height of the body. The white box will always be as tall as the window even if the content isn’t tall enough to fill in that space.

The gray box in this example also has a min-height of 100%, but it’s containing block (the white box) has a height that IS dependant on the height of its children. Therefore the min-height property of the gray box is treated as having a value of 0, preventing it from taking up the full vertical space of the page (like the white box).

Therefore, a child element whose immediate parent element has a min-height value set cannot itself have a min-height value. In other words: no nesting min-height elements.

Furthermore this min-height:100% will only work on an immediate child of the BODY element. It turns out this little CSS trick has a very limited scope. So if you ever use it be sure you understand what you’re getting into.


2 thoughts on “min-height

  1. You’re leaving me hanging!

    Your post ends with: “The gray box in”

    Is it a typo, or is there something more to come?

  2. GAH! Sorry about that. My failure with adding a closing quote to an HREF attribute killed the rest of the post. It’s been fixed.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s