Simple Tips on Containing Floats
Posted May 26th, 2009
Last updated April 13th, 2010
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.
Alert! Because you are viewing this page in an old, faulty version of Internet Explorer, the illustrations and code below may not render properly. I recommend that you upgrade to IE8, or use Firefox.
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 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.footer {
clear: both;
}
Here is the result:
A div floated left
A div floated right
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.
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.
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.
Leave a Comment
Feel free to comment. If you can improve on this post, your comments will be included, along with your name and a link to your website. (Comments are moderated, so spammers… just don't bother.)
What Now?
Search all Entries | Ebooks by Books for Learning | Services




















Comments
Comment by Alex M:
May 27, 2009
Tommy Olsson gives an example of when
overflow: hiddenwill cause problems. Rather than try to paraphrase, I'll just quote:If you have a multi-column layout where the layout order is different from the source order (not uncommon), you'll run into trouble. This type of layout is usually achieved with a combination of wrapper padding/margins, negative column margins and relative positioning. The problem is that the relative positioning puts the side columns outside the wrapper, and with overflow:hidden they become ... hidden.
BTW, you are not very clear about when
font-size: 0is actually needed.Comment by Ralph Mason:
May 27, 2009
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.Update (Dec 3, 2009): I've recently seen that Opera consistenly adds space after a "clearfixed" div unless
font-size: 0is used.