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 thanvisible
(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:
inline-block
height
width
float
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
- Visual formatting model: floats (start here)
- Investigating hasLayout
- Clearing floats
- Simple Clearing of Floats
- How to clear floats without structural markup
- How to completely enclose a floated element in CSS2
- EasyClearing, the Aslett/PIE way is NOT broken in IE7!
- Contained floats
- Clearing floats: the FNE method