Chris J Allen Chris J Allen - 6 months ago 11
CSS Question

What methods of ‘clearfix’ can I use?

I have the age-old problem of a

div
wrapping a two-column layout. My sidebar is floated, so my container
div
fails to wrap the content and sidebar.

<div id="container">
<div id="content"></div>
<div id="sidebar"></div>
</div>


There seem to be numerous methods of fixing the clear bug in Firefox:


  • <br clear="all"/>

  • overflow:auto

  • overflow:hidden



In my situation, the only one that seems to work correctly is the
<br clear="all"/>
solution, which is a little bit scruffy.
overflow:auto
gives me nasty scrollbars, and
overflow:hidden
must surely have side effects.
Also, IE7 apparently shouldn't suffer from this problem due to its incorrect behaviour, but in my situation it's suffering the same as Firefox.

Which method currently available to us is the most robust?

Answer

Depending upon the design being produced, each of the below clearfix CSS solutions has its own benefits.


"Reloaded" clearfix

Thierry Koblentz' of CSS Mojo wrote another article revisiting the clearfix, making a strong argument for dropping display: table in favor of display: block which has the advantage of not disabling margin-collapse between containers.

The latest micro-clearfix code is now:

.container::after {
    content:"";
    display:block;
    clear:both;
}

"Beat That ClearFix", a clearfix for modern browsers

Thierry Koblentz' of CSS Mojo has pointed out that when targeting modern browsers, we can now drop the zoom and ::before property/values and simply use:

.container::after {
    content:"";
    display:table;
    clear:both;
}

This solution does not support for IE 6/7 …on purpose!

Thierry also offers: "A word of caution: if you start a new project from scratch, go for it, but don’t swap this technique with the one you have now, because even though you do not support oldIE, your existing rules prevent collapsing margins."


Micro Clearfix

The most recent and globally adopted clearfix solution, the Micro Clearfix by Nicolas Gallagher.

.container::before, .container::after {
    content:"";
    display:table;
}
.container::after {
    clear:both;
}
.container {
    zoom:1; /* For IE 6/7 (trigger hasLayout) */
}

Overflow Property

This basic method is preferred for the usual case, when positioned content will not show outside the bounds of the container.

http://www.quirksmode.org/css/clearing.html - explains how to resolve common issues related to this technique, namely, setting width: 100% on the container.

.container {
    overflow: hidden;
    display: inline-block; /* Necessary to trigger "hasLayout" in IE */
    display: block; /* Sets element back to block */
}

Rather than using the display property to set "hasLayout" for IE, other properties can be used for triggering "hasLayout" for an element.

.container {
    overflow: hidden; /* Clearfix! */
    zoom: 1;  /* Triggering "hasLayout" in IE */
    display: block; /* Element must be a block to wrap around contents. Unnecessary if only using block-level elements. */
}

Another way to clear floats using the overflow property is to use the underscore hack. IE will apply the values prefixed with the underscore, other browsers will not. The zoom property triggers hasLayout in IE:

.container {
    overflow: hidden;
    _overflow: visible; /* for IE */
    _zoom: 1; /* for IE */
}

While this works... it is not ideal to use hacks.


"::after" Pseudo-element

This older "Easy Clearing" method has the advantage of allowing positioned elements to hang outside the bounds of the container, at the expense of more tricky CSS.

http://www.positioniseverything.net/easyclearing.html

.container {
    display: inline-block;
}
.container::after {
    content: "";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
    visibility: hidden;
}
.container {
    display: block;
}

Note that you should always use the double colon, ::, for before and after, unless you need to support IE8. A double colon is standard for pseudo-elements, and the single-colon implementation is deprecated and support could well be dropped in the future.


Element using "clear" property

The quick and dirty solution:

<br style="clear:both" /> <!-- So dirty! -->

Using the clearing element solution is not ideal for many reasons:

  • the main reason: you're putting presentation in your markup. This makes reusing the markup more difficult if you don't want the <br> style in another context where the same markup is used. CSS should be used to style the same markup differently in different contexts.
  • doesn't add any semantic value to your markup,
  • makes your code look unprofessional, and
  • in the future when other clearfix solutions are available you won't have to go back and remove all the <br> tags which are littered around in your markup.