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?
To put it most simply, it is because a block box with an
overflowthat isn’tvisible(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):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
clearproperty and there are preceding floats to be cleared:If you have an element with
clear: boththat’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.