clearfix Reloaded + overflow:hidden Demystified

By YUI TeamSeptember 27th, 2010


About the author:
Thierry Koblentz is a front-end engineer at Yahoo!

He owns
TJK Design and
ez-css.org. You can follow Thierry on Twitter at
@thierrykoblentz
.

clearfix and overflow:hidden may be the two most popular techniques to clear floats without structural markup.

This short article is about enhancing the first method and shedding some light on the real meaning of the second.

clearfix

In everything you know about clearfix is wrong I explain the issues this method creates across browsers and I suggest to only use clearfix on elements that are not next to floats (e.g. a modal window), although as authors we still have to deal with collapsing margins. This demo page demonstrates the issue.

Margin-collapse behavior in the first two boxes shows that it is the generated (non-empty) content that keeps the bottom margin inside the box (which makes perfect sense according to spec).

So, to create the same box layout across browsers we can enhance the original method by generating content using both pseudo-elements :before and :after:

.clearfix:before,
.clearfix:after {
  content: ".";    
  display: block;    
  height: 0;    
  overflow: hidden;	
}
.clearfix:after {clear: both;}
.clearfix {zoom: 1;} /* IE < 8 */

Don’t simply replace your clearfix rules with these new ones in existing projects, though, as you may have already patched issues related to collapsing margins via other methods.

overflow

In most discussions about clearing floats the overflow:hidden method comes up, and it is always shot down by a "If you’re placing absolutely positioned elements inside the div, you’ll be cutting off these elements". But this is not necessary true. overflow:hidden will always clip relatively positioned elements, but it will not always hide absolutely positioned ones. This is because it all depends on the containing block:

10.1 Definition of “containing block”:

4. If the element has ‘position: absolute’, the containing block is established by the nearest ancestor with a ‘position’ of ‘absolute’, ‘relative’ or ‘fixed’, …

This means absolutely positioned elements will show outside of a box styled with overflow:hidden unless their containing block is the box itself or an element inside the said box.

You can check this demo page to see how things work.

Better alternatives

If you can apply a width to the element containing floats, then your best option is to use:

display: inline-block;
width: <any explicit value>;

Further reading

12 Comments

  1. Thanks for the overflow:hidden demystification. I tend to use overflow:hidden as my default “clearfix” solution, but sometimes I had to pick another one (or I thought I had to) because of elements absolutely positioned outside the box. Now I know it’s subtler than I thought.

    display:table works too, but then you can’t use position:relative on that element.

  2. This is a good point. I’m sure many people who’re using display:table or display:table-cell are not aware of this limitation.

    Thanks for your feedback.

  3. Does your ‘Better alternative’ works in IE6, IE7, Ie8?

  4. @Jorge

    Yes it does, actually it works in IE 5.0+

    The logic is that in ie 5,6,7 the explicit width triggers hasLayout while “inline-block” creates a block formatting context in ie 8 and other modern browsers.

    The width is the key to make things work across the board though, since boxes styled as “inline-block” shrink-wrap.

    This is why the article says: “If you can apply a width to the element containing floats…”

  5. Played around with using display:inline-block & width but I found some bugs.

    If there is a space between the divs it will be showed as a space between the divs.
    Vertical alignment is a hell. @Thierry how do you use it?

    Take a look at my attempt here http://jsfiddle.net/UZr7L/

  6. @Michael

    I don’t use it on elements that are siblings (at least not for layout), but note that what you’re experiencing are not bugs.
    YUI 3 grid deals with this by using letter-spacing and word-spacing (negative values).

  7. Following this comment on Perishable Press, I noticed that I had a typo in there so I’ve updated the clearfix rule above.
    Unlike other methods, it uses overflow:hidden, not visibility:hidden.

    Thanks to Darren for raising the issue :)

  8. Apparently, using content: "020" for the clearfix is even better

  9. Ouch! WordPress chewed my code!

    It was content: "backslash zero zero two zero"

  10. @unwiredbrain

    You are referring to a technique that uses “visibility:hidden”, but what I am using is “overflow:hidden” so it should make no difference.

    Thanks for your feedback

  11. Oh. I must have confused the two. Sorry for that.

  12. Masterful. I use this on every project now as part of the HTML5 Boilerplate. I don’t use all of the boilerplate, but .clearfix always comes in handy. Thanks!!