Latest TweetsVerify any search engine or visitor via CLI Forward-Reverse Lookup perishablepress.com/cli-forwar…
Perishable Press

The New Clearfix Method

Say goodbye to the age-old clearfix hack and hello to the new and improved clearfix method..

The clearfix hack, or “easy-clearing” hack, is a useful method of clearing floats. I have written previously about the original clearfix method and even suggested a few improvements. The original clearfix hack works great, but the browsers that it targets are either obsolete or well on their way. Specifically, Internet Explorer 5 for Mac is now history, so there is no reason to bother with it when using the clearfix method of clearing floats.

The original clearfix hack looks something like this:

.clearfix:after {
	visibility: hidden;
	display: block;
	font-size: 0;
	content: " ";
	clear: both;
	height: 0;
	}
.clearfix { display: inline-table; }
/* Hides from IE-mac \*/
* html .clearfix { height: 1%; }
.clearfix { display: block; }
/* End hide from IE-mac */

Yes it’s ugly, but it works very well, enabling designers to clear floats without hiding overflow and setting a width or floating (nearly) everything to get the job done. The logic behind this hack goes something like this:

  • Target compliant browsers with the first declaration block (if all browsers were standards-compliant, this would be the only thing needed) and create a hidden clearing block after the content of the target element.
  • The second declaration applies an inline-table display property, exclusively for the benefit of IE/Mac.
  • At this point, we use the comment-backslash hack to hide the remainder of the rules from IE/Mac. This enables us to do the following:
  • Apply a 1% height only to IE6 to trigger hasLayout (which is required for the hack to work)
  • Re-apply display:block to everything except IE/Mac
  • The last line is a comment that serves to close the hack for IE/Mac

As you can see, that’s a lot of fuss over a browser that has been dead for at least the last three or four years. Nobody uses IE/Mac anymore, so it is time to drop it from the clearfix hack. The result is a much cleaner and more efficient slice of CSS:

/* new clearfix */
.clearfix:after {
	visibility: hidden;
	display: block;
	font-size: 0;
	content: " ";
	clear: both;
	height: 0;
	}
* html .clearfix             { zoom: 1; } /* IE6 */
*:first-child+html .clearfix { zoom: 1; } /* IE7 */

Stripping out that IE/Mac cruft cleans things up real nice. Notice that we have further improved the clearfix hack by adding support for IE7. Neither IE6 nor IE7 support the :after pseudo-class used in the first declaration, so we need an alternate method of applying the clearfix. Fortunately, applying zoom:1 to either browser triggers IE’s proprietary hasLayout mechanism, which works just fine to clear the float. For expediency’s sake, we accomplish this with a couple of valid browser-specific selectors, but you should be advised that conditional comments are the recommended way to go.

Fortunately, IE8 supports the :after pseudo-class, so this new clearfix method will only become more simplified as IE6 and, eventually, IE7 finally die off.

Bottom line: The new clearfix method applies clearing rules to standards-compliant browsers using the :after pseudo-class. For IE6 and IE7, the new clearfix method triggers hasLayout with some proprietary CSS. Thus, the New Clearfix method effectively clears floats in all currently used browsers without using any hacks.

Jeff Starr
About the Author Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
Archives
149 responses
  1. Besides older, non-compliant browsers, whats the point of the first block of css when you can just use clear:both;? I know that Chris Coyier uses clear:both; all of the time and seems to have little problems with it.

    So, in short, my question is this: For compliant browsers, why use multiple lines of css when you can theoretically just use 1?

  2. Ah, okay. It seems that the manner used by Chris is slightly different. He appears to use another child to perform the clearing inside the parent, rather then apply the class to the parent itself. Unless I’m mistaken.

  3. Jeff Starr

    Hi Adub, unless I’m missing something, clear:both; is useful for clearing adjacent floats, but it is insufficient to actually get container floats to clear floated child elements (such as divs).

  4. Ryan Williams December 7, 2009 @ 1:31 am

    Both are valid ways. I tend to lean towards accomplishing the clearing without any extra HTML, therefore I use both the parent and child clearing approaches.

    With that said, I’m not fond of verbose methods like Jeff’s and instead prefer to go with the overflow + dimension technique. It’s two lines, and works reliably so long as your CSS is compatible with specifying a width or height on the parent (almost always is in my experience).

  5. Jeff Starr

    @Ryan Williams: yes, the overflow fix also works great in many scenarios, and is my preferred method as well, but there are situations in which it leads to further design complications. Good examples include missing vertical scrollbars on small windows, problems with borders, padding/margin issues, outline issues, and lots of other subtle nuances. Basically, any properties made possible with some sort of a visible overflow are eliminated once you change it to hidden. This can lead to all sorts of gotchas, especially in complex layouts. Other cases where the overflow method fails is when widths or heights cannot be set explicitly, which in my experience is in a fair number of situations.

    Here is another situation where overflow fails.

    I was going to mention this line of thinking in the article, but I knew that I would have the chance to do it in the comments ;)

  6. That’s right Adub.

    If you’re willing to add an extra [div] in your code then clear:both (either inline-styling or css-class) is all you will ever need (for ALL browsers).

    However, if you rather have a div-container with in it a float-left and float-right and automaticly clear the float after the second div, then you need to “insert” an extra block-element (*:after’s are display:inline by default), that is both invisible, block-level and clearing the float.

    Hm… now that I’m thinking.. I never used the word “Insert” in this context before. Makes me think…. jQuery ?

    That’d work too !

    $ .clear-fix.parent().append("div class clearboth");

  7. Jeff Starr

    @TeMc: oooh, really like the jQuery approach :)

  8. Instead of using the invalid zoom:1 for IE7 and IE6, why not use display:inline-block for IE7 and height:1% for IE6? Those both trigger hasLayout while still using valid CSS.

    Personally I usually use the overflow method for clearing floats nowadays.

  9. Jeff Starr

    @Rob Flaherty: good call, I thought about using height:1% for the new method, but it introduces potential issues with certain layouts in IE. Besides, zoom is invalid only because it is proprietary, and even then it doesn’t matter because they are only applied to the two different versions of IE. If we follow the recommended approach and use conditional comments to include the zoom declarations, then all is well and the main stylesheet will still validate.

    In any case, it is up to you — you will use whichever property you wish for triggering hasLayout in IE. zoom is my choice because I find it the least invasive.

    As for the overflow method, see my previous comment.

  10. I generally use the overflow method since I’m really an advocate of not using unsemantic classes unless completely unavoidable. That said, I do use clearfix sometimes, but I either use it through mixins or I just repeat add the div’s selector to a clearfix code block. It might be a bit more work than just making a clearfix class, but the peace of mind it give me is mind boggling.

    Instead of => .clearfix:after {

    Id rather do tag.class1:after, tag.class2:after .... {

    It keeps the layout in the CSS where it should be.

  11. Thanks for the update. Btw, for IE 7 you can use the selector *+html for targeting. Makes it a little easier to type.

  12. Do you even need to target the zoom to only ie6/7 ?
    I’d just put zoom inside the main declaration.

[ Comments are closed for this post ]