3

html,
body {
  height: 100vh;
}

body {
  margin: 0px;
}

footer {
  height: 50px;
}

.page-wrap {
  width: calc(100% - 100px);
  height: calc(100% - 100px);
  position: relative;
  background: black;
  top: 0;
  left: 0;
  margin: 50px;
}

.content {
  min-height: calc(100% - 50px);
}
<div class="page-wrap">
  <header>

  </header>
  <div class="content">

  </div>
  <footer>

  </footer>
</div>

Using this code the body is consistently taller than the viewport, but why? I also see that setting any margin on the .page-wrap seems to create a scrollbar on body even though the height of .page-wrap is set to (calc: 100% - 100px); - I think I should have 100px of margin before a scrollbar appears, but even 1px will cause the body to become longer than the viewport..

little tiny man
  • 789
  • 4
  • 10
  • 26
  • 1
    Did you try `position:absolute`? – FDavidov Dec 10 '17 at 10:37
  • I just did, and that does correct it. I still don't understand why this is happening though... I think in this case the behavior should be the same, but in inspector it seems like with position: relative; on `.page-wrap` the body renders about 50px lower than the html element for some reason – little tiny man Dec 10 '17 at 10:38

1 Answers1

2

You are having margin collapsing which make the margin of .page-wrap goes to the parent (body) and since the height of body is 100vh, you will have the scroll because of the extra margin added.

As you can read in the link provided :

If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of its first child block; or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom of a block from the margin-bottom of its last child, then those margins collapse. The collapsed margin ends up outside the parent.

And also :

These rules apply even to margins that are zero, so the margin of a first/last child ends up outside its parent (according to the rules above) whether or not the parent's margin is zero.


You can add a small padding to body and the behavior will be removed and you will fix the issue :

html,
body {
  height: 100vh;
  box-sizing:border-box;
}

body {
  margin: 0px;
  padding-top:1px; /*added this */
}

footer {
  height: 50px;
}

.page-wrap {

  width: calc(100% - 100px);
  height: calc(100% - 100px);
  position: relative;
  background: black;
  top: 0;
  left: 0;
  margin: 50px;
}

.content {
  min-height: calc(100% - 50px);
}
<div class="page-wrap">
  <header>

  </header>
  <div class="content">

  </div>
  <footer>

  </footer>
</div>

More usefull links :

What is the point of CSS collapsing margins?

How do I uncollapse a margin?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 2
    Wow, I never knew about this effect. This seems to be the correct answer. Looking in Chrome dev tools it seems that margin collapsing isn't really illustrated, it just shows that the body element is rendering about 50px lower than with no margin shown.. The doc you supplied was super useful, but what's the purpose of margin collapsing? It seems like it would only get in the way – little tiny man Dec 10 '17 at 10:55
  • @littletinyman `what's the purpose` : am not exactly sure about the *purpose* but i simply know that it exists :) and the link i provided explains when they happen and you should always keep it in mind as it happens usually ;) – Temani Afif Dec 10 '17 at 11:10
  • 1
    I found [this answer](https://stackoverflow.com/a/3070007/2264600) on SO in response to just that. Turns out it's very useful & that I probably use it now without realizing – little tiny man Dec 10 '17 at 11:13
  • 1
    @littletinyman yes it's a good explanation :) i will then added it to my answer to be more complete ;) – Temani Afif Dec 10 '17 at 11:16