33

This question is best explained by this fiddle, with the following HTML:

<div class="outer">
    <div class="inner-left"></div>
    <div class="inner-right"></div>
</div>

CSS:

.outer {
    width: 100px;
    border: solid 5px #000;
}
.inner-left {
    float: left;
    height: 200px;
    width: 50px;
    background: #f00;
}
.inner-right {
    float: right;
    height: 200px;
    width: 50px;
    background: #0f0;
}

Basically, I'm wondering why does overflow: hidden cause the outer element to grow in height, encompassing the two floated elements?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Felix
  • 88,392
  • 43
  • 149
  • 167
  • I have no idea except that I know that it is the floats that makes it break. You have to clear the floats when you use a wrapper like that. Theres many solutions. Here's one : http://jsfiddle.net/WuqGM/9/ – Alfred Larsson Oct 08 '12 at 14:18
  • @Camhänget: Or he can choose not to clear the floats and use `overflow: hidden` as demonstrated. That said, I've edited my answer to include a note about clearfixes - the issue being described here is not a clearfix. – BoltClock Oct 08 '12 at 14:35

2 Answers2

41

To put it most simply, it is because a block box with an overflow that isn't visible (the default) creates a new block formatting context.

Boxes that create new block formatting contexts are defined to stretch to contain their floats by height if they themselves do not have a specified height, defaulting to auto (the spec calls these boxes block formatting context roots):

10.6.7 'Auto' heights for block formatting context roots

In certain cases (see, e.g., sections 10.6.4 and 10.6.6 above), the height of an element that establishes a block formatting context is computed as follows:

[...]

In addition, if the element has any floating descendants whose bottom margin edge is below the element's bottom content edge, then the height is increased to include those edges. Only floats that participate in this block formatting context are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not.

This was not the case in the original CSS2 spec, but was introduced as a change in CSS2.1 in response to a different (and much more pressing) issue. This answer offers an explanation for the changes. For this reason, it seems quite apt to call it a side effect, although the changes were very much intentional.

Also note that this is not the same thing as clearing floats (clearance). Clearance of floats only happens when you use the clear property and there are preceding floats to be cleared:

  • If you have an element with clear: both that's a sibling of the outer element in your example, the floats will be cleared but the outer element will not stretch.

  • If you have a similar element (or pseudo-element) as the last child of the outer element instead (making it a following sibling of the floats), the outer element will stretch downward in order to contain the bottom edge of that element, and for a zero-height element that essentially means the bottommost edge of the floats. This technique is known as "clearfix" because the element (or pseudo-element) has no other purpose than to force the outer element to contain the floats by way of clearance within it.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Great explaination. My question: Is there a reason NOT to use `overflow:hidden` , meaning does it have side effects which would lead us into using the clearfix technique over it? Or can either be used safely? – TetraDev Sep 21 '16 at 19:38
  • 1
    @TetraDev: Generally there are two reasons 1) exactly what it says on the tin - you *don't* want overflowing content to be clipped (or in the case of overflow: auto, you don't want the container element to generate scrollbars) 2) you want margins of non-floating elements to collapse with the container element (assuming there is nothing else already preventing margins from collapsing). In these situations, it's appropriate to use a clearing element - I recommend looking for a suitable element to apply clear to first, before considering clearfix as a last resort. – BoltClock Sep 22 '16 at 04:08
  • 1
    @TetraDev: (Interestingly, some clearfixes like the one by Nicolas Gallagher [contain extras designed to block margin collapse](http://stackoverflow.com/questions/25699262/css-using-displaytable-with-before-pseudo-element/25701312#25701312), rendering #2 somewhat moot.) – BoltClock Sep 22 '16 at 04:14
2

The way I explain it to my students is:

You trigger the element containing the floats by telling it, "everything that is to much, don't show", so the element will look for any content that is too much, and it will find some elements that are floating, now it knows that it should contain them.

zr0gravity7
  • 2,917
  • 1
  • 12
  • 33
Mark
  • 6,762
  • 1
  • 33
  • 50
  • You'd need to clarify that this applies only when you have elements that are floating, because anything else will get hidden (that's the point of `overflow: hidden`). – BoltClock Oct 08 '12 at 14:46
  • "will find some elements that are floating" i guess that will do it ? ;-) – Mark Oct 08 '12 at 14:52