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.

-1 Inline block with 100% has undesired effects when you have padding on that element. -1 :after doesnt work in ie6
–
lededjeOct 19 '12 at 10:07

7

@lededje: IE6 (hell, even IE7) has a broken float model which can never be completely remedied with any sort of clearfix.
–
BoltClock♦Oct 19 '12 at 10:38

1

@BoltClock Quite true, I also never actually tested these in actual versions of the browsers, I use(d) the Adobe BrowserLab.
–
A.M.KOct 19 '12 at 12:03

1

@lededje You may have a valid point but i'm not supposed to do all the work for you. You can test these methods and if they don't work for you find another solution or just change them, they're not that hard to understand.
–
A.M.KOct 19 '12 at 12:04

2

like seriously who cares about IE6 :D IE8, i would understand that but IE6 is too much even for 2012 :P
–
Dany KhalifeJun 21 '13 at 3:56

I usually use the overflow: auto trick; although that's not, strictly speaking, the intended use for overflow, it is kinda related - enough to make it easy to remember, certainly. The meaning of float: left itself has been extended for various uses more significantly than overflow is in this example, IMO.

The problem happens when a floated element is within a container box, that element does not automatically force the container’s height adjust to the floated element. When an element is floated, its parent no longer contains it because the float is removed from the flow. You can use 2 methods to fix it:

{ clear: both; }

clearfix

Once you understand what is happening, use the method below to “clearfix” it.

This is a bad idea. You don't want to clip anything randomly especially if you set fixed dimensions on those divs. Furthermore, there are cases where overflow: auto is preferred over overflow: hidden (e.g. you want content to be scrollable when it overflows).
–
BoltClock♦Oct 18 '12 at 16:17

1

Since I posted this, I have stopped using that as a global default. I do think that overflow:hidden is most often the best solution. Every case is different. Thanks for pointing that out ;)
–
tybro0103Oct 19 '12 at 18:31

No problem - I thought I'd add the comment anyway for posterity, in case it ever comes up again.
–
BoltClock♦Oct 19 '12 at 18:34

The ideal solution would be to use inline-block for the columns instead of floating. I think the browser support is pretty good if you follow (a) apply inline-block only to elements that are normally inline (eg span); and (b) add -moz-inline-box for Firefox.

Check your page in FF2 as well because I had a ton of problems when nesting certain elements (surprisingly, this is the one case where IE performs much better than FF).

Although the code isn't perfectly semantic, I think it's more straightforward to have what I call a "clearing div" at the bottom of every container with floats in it. In fact, I've included the following style rule in my reset block for every project:

.clear
{
clear: both;
}

If you're styling for IE6 (god help you), you might want to give this rule a 0px line-height and height as well.

if you've got something like a Facebook 'Like' box inside your element you'll need to use this method or else when you click 'Like' the Facebook comment box will be cropped.
–
Simon_WeaverJul 3 '13 at 11:01

I use 2 and 4 where applicable (i.e. when I know the content's height or if overflowing doesn't harm). Anywhere else, I go with solution 3. By the way, your first solution has no advantage over 3 (that I can spot) because it isn't any more semantic since it uses the same dummy element.

By the way, I wouldn't be concerned about the fourth solution being a hack. Hacks in CSS would only be harmful if their underlying behaviour is subject to reinterpretation or other change. This way, your hack wouldn't be guaranteed to work. However in this case, your hack relies on the exact behaviour that overflow: auto is meant to have. No harm in hitching a free ride.

Note: The IE6 and 7 width auto is used to prevent the width being 100%+padding, which is not the case in newer browsers.

A note on the other "solutions"

These fixes work back to the lowest supported browser, over 1% usage globally (IE6), which means using :after does not cut it.

Overflow hidden does show the content but does not prevent the element from collapsing and so does not answer the question. Using an inline block can have buggy results, children having strange margins and so on, table is much better.

Setting the height does "prevent" the collapse but it is not a proper fix.

Invalid css

Invalid css never hurt anyone, in fact, it is now the norm. Using browser prefixes is just as invalid as using browser specific hacks and doesn't impact the end user what so ever.

In conclusion

I use both of the above solutions to make elements react correctly and play nicely with each other, I implore you to do the same.

Since when did IE6 support display: table?
–
BoltClock♦Oct 19 '12 at 10:44

[rant] See caniuse.com/#feat=css-table, for a full compatibility list. IE 6 and 7 have no support for display: table;. As for your other solution, it's already mentioned in the question which asks for "Other suggestions". Please read the question and all answers before providing your own answer and downvoting others. Another point, invalid CSS may not "hurt" anyone but it's invalid CSS regardless, and vendor prefixes aren't just an accepted norm, look in the Chrome inspector and you'll see that it doesn't just consider them invalid, they aren't processed at all. [/rant]
–
A.M.KOct 19 '12 at 11:58

[response to rant]First of all, the above methods are tested back to IE6 and they all work just fine. Supply a non-working example and get back to me. Vendor specific rules are not meant to be processed in browsers that they don't apply to (that's what vendor specific means...) So yes, of course they are not going to be processed... that's the point, but it still allows you to use bleeding edge css rules.[/response to rant]
–
lededjeOct 19 '12 at 12:52

That your display: table method works in IE6/IE7 has nothing to do with display: table and everything to do with zoom: 1. See jsfiddle.net/BoltClock/h9GAZ/2 (removed zoom: 1) and jsfiddle.net/BoltClock/h9GAZ/3 (removed display: table). Coupled with the statement "Requires invalid css [for] IE6 and 7", that is akin to saying that method doesn't work in those versions at all.
–
BoltClock♦Oct 19 '12 at 13:37

1

zoom was never in any CSS specification... it was created and used by Microsoft alone.
–
BoltClock♦Oct 19 '12 at 16:03

You place that in your stylesheet, and all you need is to add the class 'cf' to the element containing the floats.

What I use is another variation which comes from Nicolas Gallagher.

It does the same thing, but it's shorter, looks neater, and maybe used to accomplish another thing that's pretty useful - preventing the child elements' margins from collapsing with it's parents' (but for that you do need something else - read more about it here http://nicolasgallagher.com/micro-clearfix-hack/ ).

Another possible solution which I think is more semantically correct is to change the floated inner elements to be 'display: inline'. This example and what I was working on when I came across this page both use floated divs in much exactly the same way that a span would be used. Instead of using divs, switch to span, or if you are using another element which is by default 'display: block' instead of 'display: inline' then change it to be 'display: inline'. I believe this is the 100% semantically correct solution.

Solution 1, floating the parent, is essentially to change the entire document to be floated.

Solution 2, setting an explicit height, is like drawing a box and saying I want to put a picture here, i.e. use this if you are doing an img tag.

Solution 3, adding a spacer to clear float, is like adding an extra line below your content and will mess with surrounding elements too. If you use this approach you probably want to set the div to be height: 0px.

Solution 4, overflow: auto, is acknowledging that you don't know how to lay out the document and you are admitting that you don't know what to do.

1) :after selector is not supported in IE6/7 and buggy in FF3, however,
if you care only about IE8+ and FF3.5+ clearing with :after is probably best for you...

2) overflow is supposed to do something else so this hack isn't reliable enough.

Note to author: there is nothing hacky on clearing... Clearing means to skip the floating fields. CLEAR is with us since HTML3 (who knows, maybe even longer) http://www.w3.org/MarkUp/html3/deflists.html , maybe they should chose a bit different name like page: new, but thats just a detail...