Another look at enclosing floats inside containers

This article was first published on tjkdesign.com (09-13-2010).

This article is about containing floats without structural markup. It sheds some light on the different methods commonly used and discusses a new technique…

Building a simple two column layout helps us understand all the issues at hand. Check the demo page

What we have so far

Tony Aslett/PIE

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

This technique tends to create display issues across browsers (see “what’s the difference?” below).

Paul O’brien (read PPK’s article)

.pmob {
  	overflow: hidden;
	width: 100%;
}

This method relies on creating a new block-formatting context in decent browsers and on giving the container a layout in IE Win (read on having layout). But as PPK points out in his article, giving a width to the element is not a “one size fit all” approach.

Steve Smith’s Float (Nearly) Everything Method

.FnE {
  	float: left;
}

This method creates a new block-formatting context in all browsers. As far as I know, as long as the element has a width set, it is the most reliable technique. The main issue is that you may be required to style other element(s) than the container itself (i.e. to clear it).

what’s the difference?

overflow and float are two clearing methods based on specs. Section 9.4.1 (Visual formatting model) says:

Floats, absolutely positioned elements, inline-blocks, table-cells, table-captions, and elements with overflow other than visible (except when that value has been propagated to the viewport) establish new block formatting contexts.
[…]
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
http://www.w3.org/TR/CSS21/visuren.html#block-formatting

This is true even in the presence of floats”… Which means a block formatting context will always enclose nested floats. How cool is that?

Note that this is why the “clearfix” method tends to create display issues across browsers, because the technique creates a new block-formatting context in IE, but relies on “structural clearing” in other browsers (see demo page).

What about Internet Explorer?

To “support” Internet Explorer (Win), all these techniques rely on turning “hasLayout” on (read on having layout). In the above code snippets, hasLayout is respectively turned on by:

My take on this

The challenge is to come up with a non-obtrusive technique to contains floats without creating display issues across browsers. What I mean by unobtrusive is that the method should allow authors to declare a min-height (using the _height hack) and leave them free to specifiy a width or not.

So this is how I built the rules:

Taking care of the good browsers first:

.newBFC {
    overflow: hidden;
}

Because authors use “_height” as min-height in IE lt 7, it is important to turn the above declaration off in IE lt 7.

.newBFC {
	overflow: hidden;
	_overflow: visible;
}

The declaration below is not directly related to the technique, but since we are using “overflow” I like to throw in a fix to prevent IE lt 7 from not respecting the width of a container and expanding its dimension depending on content (large image, long string, etc.).

.newBFC {
	overflow: hidden;
	_overflow: visible;
	_overflow-x:hidden;
}

Setting hasLayout in IE lt 7

.newBFC {
	overflow: hidden;
	_overflow: visible;
	_overflow-x:hidden;
	_height: 0;
}

Taking care of IE Mac

.newBFC {
	overflow: hidden;
	_overflow: visible;
	_overflow-x:hidden;
	_height: 0;
}
/**//*/
.newBFC {display: inline-block;}
/**/

In this way nested floats will be contained, container drop is avoided, and the “min-height” (_height) hack can be safely used…

If CSS validation is important to you

Use the following:

.newBFC {
	overflow: hidden;
}
/* Hide from ie Mac */
* html .newBFC {
	overflow: visible;
	overflow-x:hidden;
	height: 0;
}
/* End hide */
/**//*/
.newBFC {display: inline-block;}
/**/

Things to consider

The demo page demonstrates that this method seems to create fewer display issues across browsers.

Note that I didn’t use the word “clear” in the class name. This is because creating a new block-formatting context does not only clear nested floats, it may also lay out a box differently (as the demo page shows).

Further reading