0

Take this simple example... something I never noticed before now.

HTML:

<body>
    <div class="container">
        <div class="sidebar">
        </div>
    </div>
</body>

CSS:

*, *:before, *:after {
    box-sizing: border-box;
}

html, body, div {
    background: rgba(0, 0, 0, .2);
    margin: 0;
    padding: 20px;
    height: 100%;
    border: 1px solid #000;
}

.container {
    height: 250px;
}
.sidebar {
    width: 20%;
}

setting the height of body to 100% seems to work fine in this fiddle.

however, if you change the size of .container so that it expands beyond the initial window size... you will notice the div breaks out of the body container (it even appears to break out of the html container too)?

Reformatted Question

Is it possible to set height of the body to 100% of browser window initially but also allow the parent containers to expand with its children if it expands beyond the initial window size?

Grapho
  • 1,654
  • 15
  • 33
  • Isn't this expected behavior? If you set a child to an absolute height instead of percentage based, it will be that size, and then it's child will be 100% of it's parent. – Mathias Rechtzigel Jul 08 '14 at 16:43
  • 1
    Does `html` need to expand too? The problem is that you can get this to work for `body` by setting `min-height` instead of `height`, but while you won't be able to do this for `html` since the viewport doesn't have a pre-determined height, it should not matter because the background of `html` will be propagated to the viewport instead so you don't have to worry about it. The only problem is with the border on `html`, but I should think the border is only there for illustrative purposes. – BoltClock Jul 08 '14 at 16:47
  • The only attributes you should ever have to set on HTML are margins and padding. Never set the height of HTML, it's just useless markup. Additionally, as Bolt says, use min-height, if you want a box to expand with it content, then just let it expand. – VikingBlooded Jul 08 '14 at 16:50
  • should be `body, div {height: 100%;}` not `html,body,div{height:100%}` http://jsfiddle.net/8DJLP/13/ – Krish Jul 08 '14 at 16:53
  • why is it when I remove the `html` from my styles, then none of my % heights work? – Grapho Jul 08 '14 at 16:56
  • 1
    @Grapho: Because then there is no fixed parent height on which `body` or any of its descendants can base their height. – BoltClock Jul 08 '14 at 17:00
  • @BoltClock so then in that case, yes I do need to set html height to 100% for it to work... – Grapho Jul 08 '14 at 17:01
  • Sorry guys I need to reformat my question... – Grapho Jul 08 '14 at 17:02
  • Are the borders required? Or are they just there for illustration? If the borders are not important, then the solution is in my original comment and I can expand it into an answer. – BoltClock Jul 08 '14 at 17:09
  • @BoltClock I see how your first comment helps. setting min-height for the body works perfect... however, It is neccessary to force html to have 100% height set also.. otherwise the body will not be full browser height by default, we can see it in the fiddle by adding and removing the height property of the html tag http://jsfiddle.net/8DJLP/44/ ... if you want to post it as an answer i will mark it for you – Grapho Jul 08 '14 at 17:17
  • Yes, that is intentional. I'll post an answer to explain why. – BoltClock Jul 08 '14 at 17:18

3 Answers3

2

Typically, when you want to have html and body take on the height of the viewport but also allow them to expand with the content, you set height: 100% on html only, and min-height: 100% instead of height on body. Further explanation can be found in my answers to the following questions:

Unfortunately, because html is the root element, you cannot set min-height on it alone, or everything will fall apart. You need height: 100% because otherwise there is no parent height on which to base body and its contents; the height of html itself is based on the height of the viewport, which as you may have guessed is pre-determined.

This will be problematic if your actual layout has borders on all these elements, so instead I'm going to assume the borders aren't actually needed. You do not need to worry about the background because it will automatically be transferred to the viewport allowing it to cover the entire painting area (details in the second link).

Given your CSS, you can simply set height: auto on body to cancel out the height: 100% in your previous rule, along with min-height: 100%:

html, body, div {
    background: rgba(0, 0, 0, .2);
    margin: 0;
    padding: 20px;
    height: 100%;
}

body {
    height: auto;
    min-height: 100%;
}

Note that I've also removed the borders, again based on my assumption that they're not needed.

Now we have another problem: once the content grows beyond the browser height, the padding on html disappears, since html doesn't expand along with the other content due to height: 100% (scroll to the bottom to see this).

You can't remove height: 100% since it's required, but you can still change the padding on html to margins around body instead because the margins will continue to take effect even once body overflows html, resulting in the following (again, scroll to the bottom):

html, body, div {
    background: rgba(0, 0, 0, .2);
    margin: 0;
    padding: 20px;
    height: 100%;
}

html {
    padding: 0;
}

body {
    height: auto;
    min-height: 100%;
    margin: 20px;
}
Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Thanks for this. and yes, the borders were only there to help illustrate the original issue of overlapping elements. – Grapho Jul 08 '14 at 17:44
0

The default behavior when an element is set to 100% height is to fill its parent entirely, minus the parent's padding value.

0

Its your padding. I put your code in Dreamweaver and began to check to see why it was doing that. You're right, it works just fine until it smacks out of the viewport by changing the height. I fixed the issue by removing the padding. I suggest reworking how you organized your padding or try using something fill space without using padding. (Such as margin: 5px; for example on the outer layers instead using padding on the inside of the layers. You can even just using a blank fixed height div, afix your inner divs to a percent, and rinse and repeat. Its a dirty method.)