Simple Tips on Containing Floats
Note: this post is from 2009, but continues to remain relevant, despite newer layout options in CSS.
The float property of CSS is a powerful way to lay out the elements of a web page. For example, an image might be floated so that text will wrap around it; or divs may be floated so that they will sit side by side.
When an element is floated, it is “taken out of the document flow”—meaning that the other elements (for the most part) act like it’s not there—and this can cause some unexpected layout results. For example, floats often need to be “contained” to avoid a common problem that is demonstrated below. Fortunately, there are some easy ways to do this.
An Example
Below is an example of a standard div (colored green) that contains two floated divs:
A div floated left
A div floated right
However, the container is only wrapping around the floated inner divs because of a little CSS containing artifice. Without it, we would actually see this:
A div floated left
A div floated right
Yikes! That’s not good (especially if you want the container to display a background image or color); yet this is normal behavior. Because floats are not in the document flow, the containing div does not see them, and so it closes right up. (If it were not for some padding on the containing div, we would not be seeing it at all in the second example.)
So we need a way to make the containing div wrap around its floated contents. Below are some well-known methods.
Firstly, here is the HTML code for the example above, to which the fixes below will be applied:
<div class="contain">
<div class="left">
</div>
<div class="right">
</div>
</div>
Using overflow: hidden
A simple fix that works in most situations is to add the rule overflow: hidden
to the CSS of the containing div, like so:
div.contain {
overflow: hidden;
}
This is perhaps the easiest way to contain floats. (It is the method used in the first example above.) In some situations it will not work, however—such as when you actually want some content to overflow the container. The following method, in contrast, avoids such problems.
Using clearfix
The “clearfix” method—devised by Tony Aslett and friends—is widely employed, and is probably the best method for containing floats. To use it, firstly add a new class to the HTML:
<div class="contain clearfix">
...
</div>
Then add this to your style sheet:
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.clearfix {display: inline-block;}
/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */
That code will make the container wrap around its floated contents like a charm. The two /* comments */
at the end for IE Mac are pretty much redundant now, so they can safely be removed if you really want to.
There is another way to use the clearfix method that avoids adding the extra "clearfix"
attribute to the mark-up. The container div already has a class value, namely "contain"
, and the clearfix code can be linked to this instead, simply by changing the word clearfix
to contain
:
.contain:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.contain {display: inline-block;}
/* Hides from IE-mac \*/
* html .contain {height: 1%;}
.contain {display: block;}
/* End hide from IE-mac */
If you wanted to apply the clearfix method to other divs with different classes or ids—such as id="main"
—you would expand the code like this:
.contain:after, #main:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.contain, #main {display: inline-block;}
/* Hides from IE-mac \*/
* html .contain, * html #main {height: 1%;}
.contain, #main {display: block;}
/* End hide from IE-mac */
… and so on.
Floating the container
A good way to contain floated elements is to float the container as well. This will always work to contain the floats; but it is not always appropriate, such as when the container is a horizontally centered page wrapper. (The wrapper would no longer be centered on the page.)
When floating the container, it is necessary to give it a width to prevent it from shrink-wrapping the contents:
div.contain {
float: left;
width: 96%;
}
Result:
A div floated left
A div floated right
Using CSS table display
Another method for containing floats is to use display: table
. The downside is that this approach will not work in IE versions 7 and under. Even in proper browsers, we must give the container a width to have our example appear as it did in the first example; otherwise, it will shrink-wrap the floats. (This is not a bug, mind you, but natural table display behavior.)
Here is the CSS code we need:
div.contain {
display: table;
width: 96%;
}
Here is the result:
A div floated left
A div floated right
Using inline-block
Similar to the display: table
method is the use of display: inline-block
. Again, this doesn’t work so well in IE versions 7 and under; and again, a width is needed on the container.
Here is the CSS code we need:
div.contain {
display: inline-block;
width: 96%;
}
Here is the result:
A div floated left
A div floated right
Using the clear property
Another way to contain floated contents is to follow the contents with a non-floated element and add clear: both
to the CSS. For example, we might add a footer div to the contents of the container:
div.footr {
clear: both;
}
Here is the result:
A div floated left
A div floated right
A non-floated footer div with clear: both
In this example, clear: left
or clear: right
could also have been used in place of clear: both
. The downside is that a bottom margin needed to be added to the floated divs to stop them touching the footer.
When no such extra div is wanted in the layout, this method can be used on the sly to contain the floats anyway. For example, simply adding an empty div (as highlighted):
<div class="contain">
<div class="left">
</div>
<div class="right">
</div>
<div style="clear:both"></div>
</div>
…produces this:
A div floated left
A div floated right
Another such solution is to add something like <br style="clear:both">
in place of the empty div. However, containing floats is an issue of presentation rather than meaning (or “semantics”, in fancy talk), so it is best to avoid adding meaningless divs or other elements like this.
Using position: absolute
Another option for containing floats is to set the container to position: absolute;
, though I can’t think of many situations in which you’d want to do this, as setting an element to position: absolute
introduces other problems in page layouts. However, it may turn out that you have floated content inside an element that is already positioned absolutely, so you’ll find that the container already wraps around the content!
Here is the CSS code we need:
div.contain {
position: absolute;
width: 96%;
}
Here is the result:
A div floated left
A div floated right
Final Notes
I haven’t said much here about issues relating to Internet Explorer versions 7 and under. The overflow: hidden
method works in IE7 (as it triggers hasLayout) but not in IE6—though the container will enclose its content if it is given a width. The clearfix method works well with IE, as does floating the container, and adding in cleared divs after the floats works tolerably. As mentioned, display: table
is not an option.
There is occasionally a problem with the clearfix method, such as extra space appearing after the containing div. This can be cured by adding font-size: 0;
to the clearfix code.
Update—2012
With the merciful demise of older browsers, the clearfix code can be greatly simplified. Here are some more modern examples:
From Thierry Koblentz:
.clearfix:after {
content:"";
display:table;
clear:both;
}
From Paul O’Brien:
.clearfix:after{
content:".";
display:block;
height:0;
clear:both;
visibility:hidden;
}
… and also this:
.clearfix:after{
content:" ";
display:block;
clear:both;
}
Acknowledgements & Links
- Tony Aslett’s article on Contained Floats.
- Big John’s article on How To Clear Floats Without Structural Markup.
- The clearfix method shown above is Jeff Starr’s slightly refined version of the original, which I find works a little better (especially in Opera).
- SitePoint’s article on Simple Clearing of Floats.
- Other good articles include these from Smashing Magazine, CSS-Discuss, orderedlist (the “float nearly everything” method), Dynamic Site Solutions, Gary Turner and Paul O’Brien.
- An interesting article by Carsonified, called Everything You Know about Clearfix is Wrong.
- A useful discussion on the SitePoint Forums.
Legacy Comments
Tommy Olsson gives an example of when
overflow: hidden
will cause problems. Rather than try to paraphrase, I’ll just quote:BTW, you are not very clear about when
font-size: 0
is actually needed.Thanks for that, Alex.
Regarding
font-size: 0
, I’m not sure, but I’m wondering if this is only an issue for FireFox 2. That’s the only browser I’ve seen this happening in, but I’d like to know if it’s still a potential issue in the latest browsers.I’ve seen that Opera sometimes adds space after a “clearfixed” div unless
font-size: 0
is used ... but I’m not sure if that happens with the latest versions.