A new micro clearfix hack
The clearfix hack is a popular way to contain floats without resorting to using presentational markup. This article presents an update to the clearfix method that further reduces the amount of CSS required.
Demo: Micro clearfix hack
Known support: Firefox 3.5+, Safari 4+, Chrome, Opera 9+, IE 6+
The “micro clearfix” method is suitable for modern browsers and builds upon Thierry Koblentz’s “clearfix reloaded”, which introduced the use of both the :before and :after pseudo-elements.
Here is the updated code (I’ve used a shorter class name too):
/**
* For modern browsers
* 1. The space content is one way to avoid an Opera bug when the
* contenteditable attribute is included anywhere else in the document.
* Otherwise it causes space to appear at the top and bottom of elements
* that are clearfixed.
* 2. The use of `table` rather than `block` is only necessary if using
* `:before` to contain the top-margins of child elements.
*/
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.cf:after {
clear: both;
}
/**
* For IE 6/7 only
* Include this rule to trigger hasLayout and contain floats.
*/
.cf {
*zoom: 1;
}
This “micro clearfix” generates pseudo-elements and sets their display to table. This creates an anonymous table-cell and a new block formatting context that means the :before pseudo-element prevents top-margin collapse. The :after pseudo-element is used to clear the floats. As a result, there is no need to hide any generated content and the total amount of code needed is reduced.
Including the :before selector is not necessary to clear the floats, but it prevents top-margins from collapsing in modern browsers. This has two benefits:
- It ensures visual consistency with other float containment techniques that create a new block formatting context, e.g.,
overflow:hidden - It ensures visual consistency with IE 6/7 when
zoom:1is applied.
N.B.: There are circumstances in which IE 6/7 will not contain the bottom margins of floats within a new block formatting context. Further details can be found here: Better float containment in IE using CSS expressions.
The use of content:" " (note the space in the content string) avoids an Opera bug that creates space around clearfixed elements if the contenteditable attribute is also present somewhere in the HTML. Thanks to Sergio Cerrutti for spotting this fix. An alternative fix is to use font:0/0 a.
Legacy Firefox
Firefox < 3.5 will benefit from using Thierry’s method with the addition of visibility:hidden to hide the inserted character. This is because legacy versions of Firefox need content:"." to avoid extra space appearing between the body and its first child element, in certain circumstances (e.g., jsfiddle.net/necolas/K538S/.)
Alternative float-containment methods that create a new block formatting context, such as applying overflow:hidden or display:inline-block to the container element, will also avoid this behaviour in legacy versions of Firefox.
Comment on this post
Please wrap code fragments in <code> tags, wrap blocks of code in <pre><code>, and use JsFiddle to post working examples.
57 comments
Darren Armstrong says…
Nice work, very concise! I’ll be using this in my next build. Will report any bugs. Thanks.
Jatin says…
It really works, Brilliant.
Thomas says…
Really nice solution !
I will try to use it in my next project too ;-)
Thanks for sharing,
Thomas.
Colin Richardson says…
Aha! Good stuff, I shall also give this a bash and see how it goes. While overflow:hidden; serves me well 90% of the time, there is occasional hoop-jumping when it comes to clipping what should not be clipped.
Benjamin says…
For the non-IE code I’d suggest to use the standard pseudo-element notation
::after.Nicolas says…
@Benjamin: That post-CSS2.1 notation is not supported in IE 8.
Dan Cowley says…
This has literally come straight off your site and into a current project, great solution to this issue and also eliminates the downsides of using
overflow: hidden!Catalin Red says…
Nicolas, this clearfix looks very clean.
Thanks for sharing this solution and I’m looking forward to use it in my projects!
For the demo page, I’d suggest you to avoid the “double margin” bug (IE6). This way the clearfix method will be more visible when testing the demo example on IE6.
Nicolas says…
@Catalin: Thank you for bringing that to my attention! I’d overlooked it following a change to the margins used in the demo. It’s now been fixed.
Edmundo Junior says…
Oh so simple and so beautiful done!
Mark Simpson says…
Thank you Nicolas, I love this!
If you’re going to shorten from .clearfix or .clear to .cf, you might also consider dropping three unnecessary semi-colons. Every bit counts :)
Vaibhav Gupta says…
a brilliant work for clearfix..
I much appreciate..
Wouter Beeftink says…
@Mark Simpson: Unless I’m wrong, the main point of this script is removing the need to have an extra element within your HTML on which you can apply
clear: both;, not save a couple of bytes.@Nicolas: Thanks, I’m going to give it a shot in my next project. I wonder how you found out about the IE6 and 7 fix ;-)
Dr.Death says…
I’ll use this next time!
suprMax says…
Pretty nifty! Thanks!
Martin Bean says…
Great stuff! I shall look forward to using this in upcoming new projects.
Matthew Lein says…
Am I the only one that is seeing bottom margin collapse in IE7?
Are my IE7s F-ed?
I checked on 2 VMs, XP and Vista. I’m sure you guys tested this thoroughly…anyone else?
Nicolas says…
@Matthew Lein: No you’re not the only one. Thanks for bringing this up, it has exposed some interesting details.
The original demo used left- and right-floated elements (of equal height). In these circumstances, it seems that IE 6/7 will not collapse the bottom margin of the right-floated element.
However, I later simplifed the demo and only used left-floated elements, not expecting it to make a difference. This has exposed an inconsistency in IE 6/7. If the child elements are only left-floated then the bottom margin disappears and there is no obvious way to avoid this. I’m not sure if this has been documented before; I haven’t come across it. Previous clearfix articles and demos, including those by Position Is Everything and Thierry, made no mention of it either.
IE 6 gets even crazier. Under specific circumstances, IE 6 won’t collapse bottom margins when there are only left-floated children. But for that to happen, there has to be 2px or less of space between the last left-floated child and the right-most edge of the container. That “space” is measured from beyond the element’s right-margin. If you look at the demo in IE 6 you will notice that the bottom margins are not collapsed.
In short, this kind of behaviour suggests that it might actually be impossible to ensure that margin-collapsing is consistent across browsers while IE 6/7 are still in use.
There is also an inconsistency between modern browsers when using the original “micro clearfix” code. Under another set of circumstances, Firefox will leave a space between the top of the body and the first child element. This seems to happen when the first element of the
bodycontains floats but has no content (or new block formatting context) between the floats and their parent. It is not a problem with Thierry’s method and is also avoided when using clearing methods that create a new block formatting context.I hope to put together test-cases to demonstrate these behaviours. An update is in order.
Matthew Lein says…
dammit.
Thierry says…
Actually, there should be no need to add
visibility:hiddenas it is for this reason (to hide the “.”) that my method includesheight: 0;andoverflow: hidden;As a side note, there is a known issue in IE6/7 with *default* margins. In these browsers, elements that have a layout do not contain default vertical margins (they do prevent *explicit* margins from collapsing though). See: http://www.css-101.org/collapsing-margin/03.php
Great to see you working on pushing the envelop. I’m really looking forward to the *super micro* clearfix method:
:-)
Nicolas says…
@Thierry: I also thought that including
overflow:hiddenin the clearfix code would hide the generated content, but my tests in Firefox 2.0 – 3.0 had the “.” showing untilvisibility:hiddenwas included.Thanks for the heads-up about the default margin bug. Didn’t know about that one!
CSS Webstandard-Blog says…
Nice and smart CSS3 solution for clearing. Thx for sharing Nicolas! you already checked that at the new IE10 Pre-Beta?
neil says…
Am I missing something or is this redundant since using overflow:hidden does the same thing?
Nicolas says…
@Neil: Using
overflow:hiddenis an alternative method of containing floats that creates a new block formatting context (see the last paragraph of the post). It has different drawbacks; both methods are worth knowing and using when most appropriate.Bob Crosbee says…
Here’s another thought. Define the columns as table cells via css. This will stop us from using a clearfix hack.
Now before you start yelling about tables, using the table value of the display property shows how something should look in your browser. No semantic meaning so it’s perfectly fine, actually a much better solution to this problem.
Nicolas says…
@Bob Crosbee: The problem with using
tabledisplay types is that you become dependent on source order, you are often left emulating table markup, and they are not supported by IE 6/7.Shane Hudson says…
Impressive, really neat… before playing about with the example I did not believe it would actually work. Great find!
Optimise Web says…
Nice, thanks. I see it has been implemented into HTML5 Boilerplate too.
Plechazunga says…
This is fantastic. Now that clients are making me put grotesque amounts of box-shadow on everything, this certainly beats overflow:hidden.
Thanks! :)
Elements Aside says…
I’ve been using this in my latest projects, works great. However, as Dan Cederholm has pointed out, using the class name “group” is more semantic than using “cf”.
Matt says…
Very nice indeed. Am going to add this to a project I’m working on. Will post up with any bugs if I run into ‘em. Elegant solution.
Timothy Warren says…
I don’t see why I need this if I’ve got
display:inline-block, andzoom:1; display:inlinefor IE 6/7.Nicolas says…
@Elements Aside: I don’t think using a class like “group” is any better. IMO, it’s worse because it is vague and obfuscates the very specific purpose of the class. Just because some content is grouped doesn’t mean that there are any floats that need to be contained. And very common components (like floated-image + text) that require float containment could only be tenuously described as “groups”.
@Timothy Warren:
display:inline-blockresults in other effects that are distinct from the float containing that is desired. White-space in the code can affect the rendering and the width of the element can be affected.Peter says…
This is an excellent clearfix hack. Very tidy and semantic. Good work!
Ryan says…
Can someone explain why the :after is only cleared and not that and the :before?
TAI
Ian Storm Taylor says…
Would I be right to assume that if I have no interest in IE6 or IE7 support, the following would do me fine:
Since I don’t need to support the
zoom:1, couldn’t I also just have top-margins collapse successfully everywhere then and have this uber micro version?Martin Bavio says…
Ok, I need to know this. I’m reading here about the “downsides” of overflow:hidden technique. Can somebody explain me the downsides of it? Thanks!
Ryan says…
@Martin It will clip off elements that flow outside the container, absolute positioned elements for example.
Nicolas says…
@Ian Yeah, that’s all you’d need.
@Martin What Ryan said. Another example is box-shadow gets clipped.
Rhys Burnie says…
Fantastic! Here’s a simple sass mixin if anyone is interested:
Usage:
Mark says…
Looks great, and I’ve used it on one site so far. However, I don’t quite see how this is less code than the other clearfix method:
cf:after { content:"."; visibility: hidden; display: block; height: 0; clear: both; }That is just one line, if you format your CSS syntax as so. And the micro fix requires at least three lines of CSS for the three different rules.
Nicolas says…
@Mark It’s explained in the article:
If you don’t need this consistency, then you don’t need the two separate
:before, :afterand:afterrules. The old piece of clearfix code you’ve included is also missing the rule required to trigger a new block formatting context in IE6/7.Bob FiveThousand says…
Ahhhh! Lifesaver!
The old PIE method was failing me in FireFox 8+. An bunch of reasearch told me why and a little more led me here.
So thanks! :-)
Richard A. Allen says…
Just finished switching from Perishable Press New Clearfix and I confirm that it works well on Drupal 7. While the New Clearfix worked well for Firefox, I was having major consistency issues in IE6 and IE7, and other minor issues in other browsers. Congratulations, I present the Seal of Approval to the Micro Clearfix !
Thomas says…
This is really useful :) Just a question, do we have to use
:afterinstead of::after?Thanks for sharing this snippet!
Nicolas says…
@Thomas Yes, because IE8 doesn’t support the
::afternotation.Kzqai says…
Pretty weird that we still need patches like this to wrangle browsers into allowing cleaner layouts. I wonder if in there are any css3 proposals for alternatives to clearfix with floats. But I guess it wouldn’t matter for the next 20 or so years as legacy browsers were phased out anyway.
I guess the layout proposal is our next best hope?
Max says…
In Opera 11.62 if on page we have any
div.clearfixand any<div contenteditable="true">, the blocks with clearfix have additional height.Nicolas says…
@Max: That’s a strange Opera bug (example: http://jsfiddle.net/ZSy3N/1/). You can get around it by adding
font:0/0 ato the clearfix code generating pseudo-elements. This will prevent Opera from showing the extra space for the pseudo-element content. No other browser I tested had this problem.Sergio Cerrutti says…
Hey Nicolas,
The font fix is working ok, but there’s another way to avoid this bug, using a white-space inside the content attribute:
Nicolas says…
Thanks Sergio, good spot! I’ve updated the post to use a space in the content string and clarify a few other things. IIRC, I originally removed the space to avoid the potential for it to cause space to appear in the UI. But this might have been for legacy browsers that are now so rare as to be unimportant. I’ll double check.
Tokimon says…
Thanks Nicolas for this simple way to make elements wrap floating elements. It’s pretty neat.
I have one question however:
If you are generating the same code for both the
:beforeand the:afterelement, why not just applyclear: both;to the both of them, instead of singling out:afteras the only one who gets that statement? Would it interfere with something? Because by combining it into one statement, you are actually making the code even simpler:Jeremy Boggs says…
I’ve run into a slight issue in using this method. I have a div floated left, with a fixed width, and then a second div with a left margin slightly wider than the width of the left column (no width). If I apply the clearfix to any elements inside the second column, they also clear the left-floated div.
Example: http://jsfiddle.net/kKtVu/
But applying
overflow:hidden;to my second column, for example, seems to fix this.Example: http://jsfiddle.net/kKtVu/1/
I was somewhat surprised to see that the
:afterpseudo-element didn’t honor its ancestor’s left margin, or inherit the width of element to which it was attached. I’m curious if anyone else has run into this, and if there might be a better solution than the one I added in my second example.Nicolas says…
@Tokimon If you apply
clear:bothto:beforethen you end up with the element (with thecfclass) clearing preceding floats.@Jeremy That issue is true of all clearfix methods due to the use of
clear:both. To avoid it clearing floats outside of the element it is applied to, you need to create a new block formatting context. One way to do that is to useoverflow:hidden(as in your example). Other properties that trigger a new block formatting context includefloat:left|right, e.g., http://jsfiddle.net/kKtVu/2/ ordisplay:table-cell, e.g., http://jsfiddle.net/kKtVu/3/. Each property has its own drawbacks.Tom Kenny says…
There’s something really nice about seeing this used everywhere, from H5BP to Bourbon. Great work! You make web design that much easier.
@Jonic says…
If you use Sass placeholders you can save even more code. Instead of declaring the clearfix as a mixin, declare it as a placeholder like this:
And then use it like this:
Note the
@extendand the%to denote a placeholder. That will then compile to this:So everything that uses your clearfix rules are compiled and output in that one placeholder selector, rather than the CSS rules being included inside each selector.
Using Sass placeholders can dramatically cut down the amount of CSS repeated in a stylesheet. You can read more about them on Sass-contributor Chris Eppstein’s release notes for this feature.
Jeremy Boggs says…
@Nicolas Turns out I can solve my issue by adding
width: 100%;to the clearfix rule for :before and :after pseudo elements, and get rid of rule withclear:bothaltogether..cf:before,
.cf:after {
content: ” “;
display:table;
width:100%;
}
.cf {
*zoom:1;
}
See the JsFiddle. This seems to have the advantage of having the pseudo elements span the entire width of their parent and effectively clear anything above and below them. Haven’t run into any issues with this yet, so I’m curious what you think or if you foresee any issues with this approach.