1

I am having an understanding problem with the following code:

let myDiv1 = document.getElementById("myDiv1");
alert("Click me to make 'Hello' vanish");
myDiv1.style.height = "0px";

let myDiv2 = document.getElementById("myDiv2");
alert("Click me to make 'World' vanish");
myDiv2.style.height = "0";
.myClass1 {
  box-sizing: border-box;
  overflow: hidden;
  padding-top: 2em;
  padding-bottom: 2em;
  background-color: yellow;
}

.myClass2 {
  box-sizing: content-box;
  overflow: hidden;
  padding-top: 2em;
  padding-bottom: 2em;
  background-color: orange;
}
<body>
  <div id="myDiv1" class="myClass1">
  Hello
  </div>
  <div id="myDiv2" class="myClass2">
  World
  </div>
</body>

I understand the behavior of the second (orange) div: It has box-sizing: content-box;, so its height does not include the padding or the borders. Hence, when its height is set to 0, it shrinks basically by the height of the text "World", but the padding is left as-is. Since the padding exceeds the original text height, the text is still visible in the padding. Only that part of padding which is now outside the div (due to the reduced height) becomes invisible (due to overflow: hidden;).

I do not understand the behavior of the first (yellow) div, though. It has box-sizing: border-box;, so its height does include the padding and the borders. Hence, when its height is set to 0, it should shrink to "real" zero height, meaning that the text, the padding and the borders then should be outside the div and thus should be invisible (due to overflow: hidden;).

Can anybody explain why this is not the case and why the first div behaves just like the second div?

P.S. Tested in Firefox and Chrome, both up-to-date (production channel) at the time of writing this.

SapuSeven
  • 1,473
  • 17
  • 30
Binarus
  • 4,005
  • 3
  • 25
  • 41

1 Answers1

2

border-box tells the browser to account for any border and padding in the values you specify for an element's width and height. If you set an element's width to 100 pixels, that 100 pixels will include any border or padding you added, and the content box will shrink to absorb that extra width. This typically makes it much easier to size elements. ref

Here is an example to better ilustrate your issue:

.box {
  display: inline-block;
  padding-top: 2em;
  padding-bottom: 2em;
  border: 2px solid blue;
  background: linear-gradient(red, red) content-box, orange;
  height: 100px;
  animation:move 5s linear infinite alternate;
}

@keyframes move{
   to {
     height:0;
   }
}
<div class="box">
  World
</div>
<div class="box" style=" box-sizing: border-box;">
  World
</div>

The first example is the trivial one where we decrease the height (red area) until 0 and the animation never stop.

In the second case the height include the padding and border so before reaching 0 the content area is already 0 that's why the animation seems to stop because we cannot decrease more than 0 and the border/padding already consumed all the space.

It's logical that when height is equal to 0 both are the same since in the first one we tell the browser that the content area should be 0 (we don't care about padding/border) and in the second case we told the browser to account for the padding/border into the height we specified so we have less room for the content area and since we cannot have less than 0 then its 0.

In other words, you aren't setting the total height that will be split between the content area, padding and border but you are setting a height and the browser is shrinking it as much as possible to include the border and padding.

Related for more examples and details: box-sizing: border-box with no declared height/width

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thank you very much for your clear explanation (and the animation, of course) - accepted and upvoted. I had already suspected so, but wanted to know for sure. My problem was that (mainly in former days) I have seen a lot of code with negative `margin`s, `top`s and even `padding`s (and so on), and thus I thought that the content `height` eventually could (should?) become negative in this case, too. After all, this behavior takes away the main advantage of `border-box` (that is, its simplicity). – Binarus Nov 13 '19 at 14:19
  • 1
    @Binarus no, negative aren't allowed inside (height,padding,border) but only outside (margin). it would take me too long to explain the logical reason behind this but the bottom line is that there is no logical illustration of something like negative height but negative margin can be illustrated with overlapping. – Temani Afif Nov 13 '19 at 14:24