26

In this example...

HTML

<body>
  <div>
    <div>foo bar</div>
  </div>
</body>

CSS

body, html, div {
  height: 100%;
  margin: 0;
}
div div {
  display: inline-block;
  overflow: hidden;
}

Why does overflow: hidden cause a vertical scrollbar? Additionally, why is this height not attributed to anything on the page? It's like an invisible margin.

The 100% height of all the elements is intentional. In theory, that should cause the inner-most div to expand to meet the viewport. And it does! ...so long as overflow: hidden is not there, Why?

JGallardo
  • 11,074
  • 10
  • 82
  • 96
uber5001
  • 3,864
  • 4
  • 23
  • 44
  • 5
    Take a look at this topic, it may help you : http://stackoverflow.com/questions/20566710/overflowhidden-displayinline-block-moves-text-upwards – Wang Sep 12 '14 at 23:29
  • [This question](http://stackoverflow.com/questions/20310690/overflowhidden-on-inline-block-adds-height-to-parent) may be a duplicate, but the answers don't have explanations. – uber5001 Sep 13 '14 at 00:07
  • 3
    @uber5001 I didn't vote *(because it would have got closed immediately since I have a gold CSS badge)*. However, setting `vertical-align` to `top`, `middle` or `bottom` (anything other than `baseline`, `sup`, ...) aligns the inline level element with the respect of the parent's baseline or top/bottom of the line box. In this case, `bottom` value aligns the baseline of the inner `div` - which is its bottom margin - to the bottom of the line box in inline flow. Hence the UA won't count the reserved height of descenders twice. – Hashem Qolami Sep 13 '14 at 00:07
  • You could [verify](http://jsbin.com/zowejokuluce/7/edit) [that](http://jsbin.com/zowejokuluce/8/edit). – Hashem Qolami Sep 13 '14 at 00:12
  • @Hashem Qolami, you seem like you know the answer. Why not format it as an answer? or mark as duplicate and put a better answer to the old question? (I don't think the current suggestion for duplicate is a duplicate...) – uber5001 Sep 13 '14 at 00:15
  • @uber5001 Because my explanation doesn't answer `Why does overflow: hidden add additional height` nor `overflow:hidden + display:inline-block moves text upwards`. It just explain the effect of `vertical-align: bottom` in this particular instance which is not the subject of these two questions. – Hashem Qolami Sep 13 '14 at 00:21
  • Just solved it with vertical-align: bottom :) – Tony Gustafsson Apr 08 '16 at 14:34

3 Answers3

25

The extra height is the same height as the height difference between vertical-align: baseline, and vertical-align: bottom. The "descender line". That's where the seemingly random "5 extra pixels" comes from. If the font size is 10 times as large, this gap will also be 10 times as large.

Also, it seems that when overflow: hidden is not there, the inline-block element has its baseline as the same baseline of its last line of text.

This leads me to believe that overflow: hidden forces the baseline of the entire inline-block element to be at the bottom of the element. Even though there is no text there, the parent of the inline-block element reserves space for the descender line. In the example given in the question, it cannot be easily seen since the parent of the inline-block element has height: 100%. So, instead, that extra space reserved for the descender line overflows out of that parent div.

Why is this space still there, even though there's no text? I think that's because the inline-block creates an inline formatting context, which is what causes this space. Were this element to be a block, it would only create this inline formatting context once it encounters an inline element or text.

This is just a theory, but it seems to explain it. It also explains why @Jonny Synthetic's answer works: adding overflow: hidden to the parent hides that extra descender line.

Thanks to @Hashem Qolami for the jsbins that gave me this theory.

Community
  • 1
  • 1
uber5001
  • 3,864
  • 4
  • 23
  • 44
  • 3
    You've got it all pretty much right. The inline-block with overflow hidden vertically aligns its bottom margin edge with the baseline of the line box's [strut](http://www.w3.org/TR/CSS2/visudet.html#strut). The line-box then has to be tall enough to contain the inline-block div and the strut, including that part of the strut which is below the baseline. That makes the line box (and hence its block container) taller than 100% of the initial containing block and so the html element gains a scrollbar to allow the whole content to be seen. – Alohci Sep 13 '14 at 02:05
10

Adding overflow: hidden to the parent div wasn't an option for me, and also because of my HTML's structure it wasn't working.

However, I noticed thanks to @Tony Gustafsson's comment in the OP that this does fix the problem:

div div {
    vertical-align: bottom;
}
Community
  • 1
  • 1
Hewbot
  • 370
  • 4
  • 10
  • All credits to Tony, I just posted this to make it more visible (it took me a while to see his solution). – Hewbot Apr 06 '17 at 21:36
2

Items with a height of 100% need to have overflow: hidden as well. The first css rule only targets the outside div, the overflow hidden is being applied to the inside div.

Jsfiddle with this CSS and it worked fine:

body, html, div {
    height: 100%;
    margin: 0px;
    padding:0px;
    overflow: hidden;
}
div div {
    display: inline-block;
    overflow: hidden;
}
  • 3
    It seems like this just hides the problem with another `overflow: hidden` rather than explaining why the first `overflow: hidden` added overflow in the first place. Is that why this works? Why is that extra few pixels there in the first place? – uber5001 Sep 12 '14 at 23:32