Html, body questions

If you want something 100% height (e.g. a div) to take up the full viewport you need to do:

html, body { height: 100%; }

However, if you’re using absolute or fixed position, this will do it:

html { height: 100%; }
body { min-height: 100%; }
  1. Why doesn’t the second code listing work if you want to make a div height 100% with static positioning?
  2. If you set html and body to height 100% without min-height and put loads of content in the body (so much so that it takes up a lot more than the viewport) there is still vertical scrolling even though by default html and body’s overflow is set to visible. Why is this? I’d expect it to get clipped at the bottom of the viewport.
  3. How come if you put an absolutely positioned element with top and bottom set to 0 it takes up the full height of the viewport even if the HTML element is shorter than the viewport?

EDIT: On Safari and Chrome html and body’s overflow is set to visible whereas I’ve read the default should be auto…

Thanks.

If I were to guess, default margins and paddings are to blame for that, but I’d really like some codepen for exemplification, it’s not very clear what you’re asking about without a proper example.

Do you use a reset?

1 Like

codepen doesn’t allow you to use the HTML or body tag as far as I know so three HTML files attached relating to my three questions.

Comments:

question1.html: html is height 100% and body is min-height: 100% so why isn’t body the full width of the viewport? If it was the red div would be full height.
question-2.html: html has a green border. The red div is absolute from top 0 to bottom 0. Shouldn’t the red div be contained within the green HTML element?
question-3.html: html and body both have overflow visible (which seems to be the default in webkit anyway) and height: 100%. Why is there a scrollbar? Visible means the content just goes outside the element with no scrollbar so should the html element clip off the content outside the viewport?

Thanks for looking.

question-1.html (255 Bytes) question-2.html (36.7 KB) question-3.html (310 Bytes)

@malona For the purposes of this demo I’m just setting the padding and margin of the body to 0. See attached files above.

Static elements cannot base their height on a parent unless that parent has a fixed height (not auto and not min-height). If the parent has a percentage height then that parent must have its height based on another parent of fixed height and so on up to the viewport (which is why you need html and body to have height:100% when you want the first div on the page to have a min-height of 100%) .

Absolute elements on the other hand can base their height on their nearest positioned parent element even if that parent’s height is controlled by content, auto height or min-height. Which is why you can make an absolute element fill the viewport easily (an absolute element is placed in relation to its nearest positioned element and if none exists it is placed in relation to the viewport).

If you want a succession of 100% heights then you can use display:table (ie8+) as height is treated as a minimum for display :table elements but remember you will always get a full 100% so you can’t apply this to elements that are some way down the page because then they will go below the viewport.

  1. The body is min-height:100% which means its height is auto and you cannot base a percentage height on an auto height element. Even if it worked your element could never grow because it would be fixed to that initial 100% height (which would also be the case should you give the body a 100% height and then your 100% height div could never grow pass that limit - the div would need to be min-height:100% and html and body at 100%).

Your question-2.html doesn’t have those rules - did you post the wrong file?

Yes visible is the default so no need to specify it but the specs say “The ‘visible’ value when used for the viewport must be interpreted as ‘auto’”. This means that visible content that overflows any container will still be reached in the viewport via a scrolbar on the viewport.

Height:100% is a tricky concept and in the case of the html and body when you set them both to 100% what happens is that they give you an initial 100% but then content in the page overflows this 100% eventually but because of the rules above but this causes no problems because the scrollbar on the viewport is maintained as mentioned in the specs. On the other hand if you overflow a 100% high div then the content spills out and a scrolbar isn’t triggered on that div and content will overlap.

2 Likes

The html element’s dimensions are initially controlled by the size of the viewport so html will always cover the viewport - it still means that its height is auto though.

A positioned element is placed in relation to the nearest ancestor with a position defined (other than static). If no such parent exists then the element is placed in relation to the root element (the html element - effectively the viewport). As discussed earlier an absolute element can base its height on its positioned parent’s intrinsic height (unlike other elements) so you easily get an element that spans the viewport height.

1 Like

Paul, that is an absolutely terrific answer. Thanks for going thorough it in so much detail. Sorry, I got my HTML files mixed up and question-2 and 3.html were the wrong way round.

I’ve been using CSS for ages and it’s amazing that I’ve never really understood this correctly.

You picked up on it though in your most recent answer.

So just to reiterate if you want to do things “full height” setting both html and body to height: 100% is the best way and won’t lead to clipping of content per the spec. Correct? I guess min-height isn’t needed here then.

You are on the right track. The key thing to understand is this this is a one shot deal.

That is one you reach the level of setting “min-height” it would not make sense to set height on the same element; and because you haven’t set height on that element setting a % heigh on a child element would be ambiguous. (In other words, min-height is not height,and does not cascade)

The other important take away is… you can’t hide the overflow in the elements that are 100% height. You are setting the 100% height on the parent element to cover instances when there is not enough content to fill the window and counting on the overflow for when there is more.

throw in , now , the behavior caused by fixed and absolute positioning… and you should be able to fairly accurately guess how each nested element will behave.

hope that helps

1 Like

In most cases yes this is the bare minimun:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>
html,body{height:100%;margin:0;padding:0}
.wrap{
	min-height:100%;
	max-width:960px;
	margin:auto;
	background:red;	
}
</style>
</head>
<body>
<div class="wrap">100%</div>
</body>
</html>

There are cases where setting 100% on html and body could have strange effects and that would be when applying backgrounds to both html and body and then you would get html background at 100% only and the body background below the fold. In most cases you should avoid setting styles on html anyway, apart from height:100% and resetting margin and padding.This is because the body is special and when you apply a background to the body it is automatically propagated to the html element anyway and thus solves any overflow problem.

Actually many so called experts do not understand this properly either :smile: It took me a while to get my head around it.

3 Likes

Thank you, I’ve learnt a lot from this!

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.