Entry updated 24th September 2006: added browser support tables and made minor corrections.
Floating elements within a container can be frustrating if the container has a background image, colour or borders. You'll mostly likely have seen something similar to the result shown below:
The parent container doesn't stretch down to enclose its children. The W3C recommendations specify that this is correct behaviour. But why? It certainly looks wrong. If you're using Internet Explorer 6 or below and have applied a dimension (width or height) to the container you'll wonder what all the fuss is about - it seems to behave the way we want it to.
Lets take a look at another example. This one contains two paragraphs of text and an image which has been floated left. As we'd expect the text wraps nicely around the image.
Nothing strange here, but lets look at the same example with borders applied to each of the paragraphs.
Notice how the image appears to drop out of the bottom of the first paragraph. Without the seemingly strange behaviour we witnessed previously it would be impossible to make the text wrap effectively around the image.
This is all well and good but what if this really isn't the behaviour we want? Fortunately there are a number of methods we can use to force the container to enclose its floated children.
Clearer DIV Method
Probably the simplest and a popular solution is to add an extra DIV with the style clear:both below your floated elements. I don't like it though, it adds unnecessary markup to your page which is associated with presentational display.
| IE 5.0 | IE 5 Mac | IE 5.5 | IE 6 | IE 7 | Firefox 1.5 | Opera 9 | Safari 2 |
|---|---|---|---|---|---|---|---|
| Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
Overflow Method
Adding overflow:auto to your container element will also achieve the desired effect. For IE 6 and below you'll also have to add a width or height to the container to force hasLayout. In this example I use width:100%. If you're concerned about Mac IE you'll have to use overflow:hidden rather than overflow:auto as with overflow:auto it always shows scrollbars.
If you're not concerned about supporting IE 5.0 or Mac IE then the proprietary zoom property (zoom:1) might be a better bet than width:100% although it does mean your CSS won't validate.
| IE 5.0 | IE 5 Mac | IE 5.5 | IE 6 | IE 7 | Firefox 1.5 | Opera 9 | Safari 2 |
|---|---|---|---|---|---|---|---|
| Yes (width: 100%;) | No (but works with overflow:hidden) | Yes | Yes | Yes | Yes | Yes | Yes |
Easy Clearing Method
In standards compliant browsers this method makes use of the rarely used pseudo :after class to append a single "block level" full stop after your floated child elements with a clear:both rule specified which forces the container to stretch down to enclose its children. The full stop is hidden from view using visibility:hidden and height:0 ensures it takes up no vertical screen space. This technique is the CSS equivalent of the "Clearer DIV method" described above.
For Win IE, which doesn't support this class, an additional height:1% rule was originally added to trigger hasLayout. This was hidden from other browsers using the star html hack and, in the case of Mac IE the backslash comment hack. With the imminent release of IE 7, which no longer treats width and height as if they were min-with and min-height, specifying this rule is harmful.
Fortunately toggling the display property from inline-block to block triggers hasLayout and forces the container to enclose its children in IE 5.5, 6 & 7. This doesn't work in IE 5.0 so we need to keep the height:1% rule but hide it from IE 7 using the underscore (or alternatively star html) hack. Some examples use "zoom" to trigger hasLayout in IE but this property isn't supported in IE 5.0.
Switching to display:inline-block does the trick for Mac IE but the second part of the toggle, switching back to display:block needs to be hidden. This can be done using the Mac IE backslash comment hack.
| IE 5.0 | IE 5 Mac | IE 5.5 | IE 6 | IE 7 | Firefox 1.5 | Opera 9 | Safari 2 |
|---|---|---|---|---|---|---|---|
| Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
If you're not concerned about supporting Win IE 5.0 and Mac IE the example can be written more simply. At a first glance you might be tempted to combine the #container { display: inline-block; } and #container { display: block; } rules into one line but you'll find the clearing effect stops working if you do.
| IE 5.0 | IE 5 Mac | IE 5.5 | IE 6 | IE 7 | Firefox 1.5 | Opera 9 | Safari 2 |
|---|---|---|---|---|---|---|---|
| No | No | Yes | Yes | Yes | Yes | Yes | Yes |
Clearing with Additional Floats
Adding a float:left or float:right to the container DIV will also force it to contain its children. This method does have a couple of drawbacks. Firstly the container will "shrink wrap" to the size of its child elements. This means you may need to add an explicit width to maintain the original width of the container. Secondly you'll have to add a clear rule to any element immediately following the container in the source.
| IE 5.0 | IE 5 Mac | IE 5.5 | IE 6 | IE 7 | Firefox 1.5 | Opera 9 | Safari 2 |
|---|---|---|---|---|---|---|---|
| Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
Finally! An article that trully and simply explains the "whys" (and even better!! all the whys!!) for something that has happened a lot of times during my work and which I always had to find ways around. Great post overall!
And, missing in your last example (floating the container) it becomes very hard to center the container. Floats don't react to {margin:0 auto} which would be the preferred way.
Great article, explaining the reasons for these errors...
Thanx!
@Michiel - you're absolutely right, thanks for pointing this out. The floating method does have its problems and is also the only one which isn't self contained. You can't simply drop the container block into another section of code without thinking about what surrounds it.
Before reading this I would just use the "Clearer DIV Method" and I agree it isn't a nice solution because of the unnecessary markup it ads So thanks for the great article.
Here's one I learned. Set "display: table; width: 100%;" PC IE6 and Firefox friendly, though safari starts getting weird when you get to adding padding to it.
Is it me, or is this post basically a summary of http://complexspiral.com/publications/containing-floats/ ?
Hi Eric - thanks for stopping by. Obviously we're both looking at the same problem, as are many others, but your article only explains two of the methods described here (missing the easy clearing and overflow methods). I've also tried to go further by implementing a rule vs browser support chart to hopefully help people understand which parts of each method effect each browser. This would also allow one to mix and match rules to create a custom clearing rule set.
I sure hope that's someone POSING as Eric Meyer. I'd hate to think the real Eric Meyer is so arrogant as to assert that his 3-year-old tutorial is The Last Word on floats.
@Michiel - Another alternative is to set "body {width:780px; margin:0 auto;}". This will center the content, and enable you to float you container div. And, of course, you can set the width of the body to whatever you want. And you don't need an extra container to achieve the desired result.
Hi, never understood the use of the period in the pseudo-element (it's not a class)
.
The following is totally sufficient:
You don't need to set visibility and won't pollute your page with periods.
From what I take away from this article, despite the extra DIV, its still better to use the first, tried and tested clearer div method. I cant responsibly use css hacks in the sites I create for clients because then when a new browser comes out they have a broken site and have to pay for support. And also i've never understood why everyone gets so persnickety about extra div tags in documents as they have absolutley no detremental effect in any browser, for mobiles, disabled people, old browser software, etc.
Thank you for this compendium! I've found the overflow method to be the best one. To answer rtpHarry, using any of the other methods in moderately complex layouts is delicate, lest you clear out of the various left- and right-floated columns.
I've been looking at this problem for some time. It all depends on what works for a layout. I would go with either the FnE method (Float Nearly Everything) or the Clearing method for more complex layouts and ensuring browser compatability (safe route). One way I've done it is with an hr, as suggested by Eric Meyer. Semantically, I would say this is preferrable over a div or br with a   inserted. To combat IE's forcing of vertical space, put a conditional statement to use negative top and bottom margins. Also, the space at the bottom of the float could be a little flexible, so it worked just fine for that case. Also, I just had to make a seriously complex layout... I used both methods of FnE and Clearing.
By the way...this is help on the way eventually:
http://www.w3.org/TR/2002/WD-css3-box-20021024/#the-clear-after
Congratulations. This is the best summary I have read on these various clearing methods, and your browser charts are indeed useful.
Please keep this page up, and updated, as it is a truly valuable resource.
Well done!
this is great, very helpful. thanks!
Thanks for your great explanation about floats.
Tuttle, Michelle, Martin - thanks for the feedback. I'm pleased the explanation was helpful.
Yes, i found the easy clearing method also very useful.
Thank you.
Is there any merit to using one of these in your html?
I then write a css rule that makes sure all brs have no height.
Seems to be working across all browsers.
Sorry, the missing pieces is in brackets...
br clear="all" /
This is fabulous - I've spent a lot of time scouring the forums and CSS sites and I haven't found any article as helpful as this. The overflow:auto method allowed me to expand my container while keeping it centered, unlike the clearfix method which requires the container to float right or left.
Priceless!
Thank you!!!
oh god... this float think almost have me quit css for good... really saved my day..
Stumbled across this article today as I was struggling with this exact problem. Your suggestions worked flawlessly! Thanks.
Re: Brad "I then write a css rule that makes sure all brs have no height."
You really shouldn't be adding extra markup to contain floats. What if you won't need clearing in certain place, but a real . What if later you decide that in that one spot where you cleared with markup you'd rather have it not cleared. Sure, if you have a 4 paged site and decide to add 5th one it will be snap to edit something and then check that the other 4 look good, but what if your site has 1000 pages with 100 different templates?
The point of CSS in the first place is to separate content from presentation.
I can't think of a test case where you'd _have_ to use extra markup. Although, I may say that I've seen some IE bugs where some extreme hackery would be required.
A rule of thumb in choosing the method to contain your floats (considering each have drawbacks and can't be used in every possible situation) is:
Overflow => .clearFix (aka EasyClearing aka :after method) => Float on the container => extra markup (aka "clearing div" or "br") and I am happy to notice that this great tutorial lists them in such order.
Great tutorial, I hope the link is permanent 'cause I am linkin' :)
s/, but a real//; # thought jumps :)