Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why bottom positioned footer inside <html> moves below viewport if <html> height is always equal to viewport's height

Tags:

html

css

This article states that height of the <html> element is calculated by a browser and always equal to the height of the viewport, see the picture for quick reference. So in this sticky footer example the footer is absolutely positioned at the bottom inside <html> element and moves down if the content is over 100% of the viewport's height. If it moves down than I assume that the height of the <html> element gets bigger than 100% of the viewport, which contradicts the article mentioned in the beginning. What am I missing?

UPDATE based on Hashem Qolami's answer:
Initial containing block has height and width automatically calculated by the browser and is always equal to viewport dimensions. HTML element height is relative to its contents, BUT if we give it explicit height of 100% it takes 100% of the height of its containing block which is initial containing block with the height equal to viewport's. Are these conclusions\main points correct?

like image 902
Max Koretskyi Avatar asked Sep 30 '22 21:09

Max Koretskyi


1 Answers

Do not let that article deceive you. At first look it may seem confusing but I'll try to show you how the browser deals with <html> element.

The html element's height and width are controlled by the browser window.

This is true for the width but not true for the height.

<html> element - like block-level elements - takes the entire horizontal space of its containing block1 which is the initial containing block:.

The containing block in which the root element lives is a rectangle called the initial containing block. For continuous media, it has the dimensions of the viewport and is anchored at the canvas origin; it is the page area for paged media.

However its computed height is relative to its contents by default, unless you give it an explicit height2. Hence the following statement is NOT true:

height of the <html> element is calculated by a browser and always equal to the height of the viewport

Now you may ask "If the <html> doesn't take the height of the viewport, why does giving a background-color to the <html> changes the background color of the viewport?"

This is because the viewport takes the background color of the root element, the <html>. This is documented in the spec:

3.11.1. The Canvas Background and the Root Element

The background of the root element becomes the background of the canvas and its background painting area extends to cover the entire canvas. However, any images are sized and positioned relative to the root element as if they were painted for that element alone. (In other words, the background positioning area is determined as for the root element.) The root element does not paint this background again, i.e., the used value of its background is transparent.

In addition, if the background color of the <html> is not specified, it'll take the background color of the <body> (if there's any) and it'll pass it to the viewport. This is has been described in the spec. Also you might want to have a look at this topic on SO:

  • Applying a background to <html> and/or <body>

But again you may wonder "why an absolutely positioned element is positioned with the respect to the viewport rather than the <html> element"3

The answer will be because absolutely positioned elements are positioned relative to their containing block. fixed positioned elements respect to the initial containing block which takes the dimensions of the viewport. And absolute positioned elements respect to their containing block which is established by the nearest ancestor with a position of anything other than static.

The key point is:

If there is no such ancestor, the containing block is the initial containing block.

Therefore an absolute positioned element - having bottom: 0 declaration - inside <html> won't be placed with the respect to the <html> itself, but to the initial containing block, i.e. the viewport; Example Here.

In order to position it relative to the <html>, we have to establish a containing block for it by giving the <html> a position of relative; Example Here4


That being said, if you give the <html> a height of 100%, it will take 100% of height of the viewport, but if its contents get that bigger that exceeds the computed height, it'll overflow the <html> element. Thus, the absolute positioned element won't be placed at the bottom of the page anymore.

I assume that the height of the element gets bigger than 100% of the viewport

Your thought is true. This is because of using min-height: 100% declaration on the <html> rather than height property.

From the MDN:

The min-height CSS property is used to set the minimum height of a given element. It prevents the used value of the height property from becoming smaller than the value specified for min-height.

It lets the <html> get higher than the viewport (by its contents).


1Folks sometimes use the term of "parent" in order to refer to the box's containing block. That's a Lie-to-children! In fact block-level elements respect to the width of their containing block in which they are sit.

2In the demo, the red box shows the border-box of the <html> element and the blue box belongs to the <body>.

3Assuming the <html> doesn't take the entire height of the viewport by default.

4This is exactly what has been done in the Twitter Bootstrap's sticky footer example.

like image 136
Hashem Qolami Avatar answered Oct 03 '22 00:10

Hashem Qolami