Although elements like <div>
s normally grow to fit their contents, using the float
property can cause a startling problem for CSS newbies: If floated elements have non-floated parent elements, the parent will collapse.
For example:
<div>
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
The parent div in this example will not expand to contain its floated children - it will appear to have height: 0
.
I would like to create an exhaustive list of solutions here. If you're aware of cross-browser compatibility issues, please point them out.
Float the parent.
<div style="float: left;">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
Pros: Semantic code.
Cons: You may not always want the parent floated. Even if you do, do you float the parents' parent, and so on? Must you float every ancestor element?
Give the parent an explicit height.
<div style="height: 300px;">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
Pros: Semantic code.
Cons: Not flexible - if the content changes or the browser is resized, the layout will break.
Append a "spacer" element inside the parent element, like this:
<div>
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
<div class="spacer" style="clear: both;"></div>
</div>
Pros: Straightforward to code.
Cons: Not semantic; the spacer div exists only as a layout hack.
Set parent to overflow: auto
.
<div style="overflow: auto;">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
Pros: Doesn't require extra div.
Cons: Seems like a hack - that's not the overflow
property's stated purpose.
The most reliable and unobtrusive method appears to be this:
Demo: http://jsfiddle.net/SO_AMK/wXaEH/
HTML:
<div class="clearfix">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
CSS:
.clearfix::after {
content: " ";
display: block;
height: 0;
clear: both;
}
With a little CSS targeting, you don't even need to add a class to the parent DIV
.
This solution is backward compatible with IE8 so you don't need to worry about older browsers failing.
An adaptation of solution 1 has been suggested and is as follows:
Demo: http://jsfiddle.net/wXaEH/162/
HTML:
<div class="clearfix">
<div style="float: left;">Div 1</div>
<div style="float: left;">Div 2</div>
</div>
CSS:
.clearfix::after {
content: " ";
display: block;
height: 0;
clear: both;
*zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML += '<div class="ie7-clear"></div>' );
}
.ie7-clear {
display: block;
clear: both;
}
This solution appears to be backward compatible to IE5.5 but is untested.
It's also possible to set display: inline-block;
and width: 100%;
to emulate a normal block element while not collapsing.
Demo: http://jsfiddle.net/SO_AMK/ae5ey/
CSS:
.clearfix {
display: inline-block;
width: 100%;
}
This solution should be backward compatible with IE5.5 but has only been tested in IE6.