Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a 1px border cancel out a 100px margin-top and kills a scrollbar?

This doesn't yet make sense to me. What am I missing?

Uncomment the border to kill the scrollbar

The code is below and on Codepen.

* {
  box-sizing: border-box;
  margin: 0; padding: 0;
}

body {
  height: 100vh;
  background: pink;
}

.middle {
  position: relative;
  top: 200px;
  /* uncomment the border to kill the scrollbar! */
/* border: 1px solid green; */
}

.middle div {
  margin-top: 100px;
  border: 1px dashed yellow;
}
<div class="middle">
  <div>Text</div>
</div>

box-sizing: border-box; doesn't make any difference. Adding a border causes the vertical margins to not collapse, but what exactly is going on?

  • with border: no scrollbar
  • without border, the two top margins collapse, so there should be less vertical space required, yet we get a vertical scrollbar on the full-height body.
like image 252
Dan Dascalescu Avatar asked Jul 07 '15 07:07

Dan Dascalescu


1 Answers

This is due to margin collapsing:

If there is no border, padding, inline content, or clearance to separate the margin-top of a block with 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 with the margin-bottom of its last child, then those margins collapse. The collapsed margin ends up outside the parent.

(https://developer.mozilla.org/en-US/docs/Web/CSS/margin_collapsing)

When .middle does not have a border the margin applied to .middle div ends up outside of it effectively making body have height: 100vh; and margin-top: 100px;. This is what causes the scrollbar.

With the border on .middle the margin is contained within .middle so body just has height: 100vh; and no scrollbar.

As confirmation of this, you will find that you get the same outcome if you were to add a border to body instead.

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
body {
  height: 100vh;
  background: pink;
  border: 1px solid red;
}
.middle {
  position: relative;
  top: 200px;
  /* uncomment the border to kill the scrollbar! */
  /* border: 1px solid green; */
}
.middle div {
  margin-top: 100px;
  border: 1px dashed yellow;
}
<div class="middle">
  <div><a href="https://iDoRecall.com">Text</a>
  </div>
</div>
like image 106
Hidden Hobbes Avatar answered Sep 19 '22 13:09

Hidden Hobbes