Making Elements Contain Floated Children

posted by Kravvitz at 9:32 PM on Jul. 12th, 2010

Categories: HTML, CSS, Browsers, Bugs 0 comments

There are several ways to cause an element to expand in height to contain its floated descendants. Of course some are better than others. (This has been discussed elsewhere before, but since not everyone is a CSS expert, I thought I'd write down my own thoughts on the strategies for dealing with this issue.)

The Old Ways

The oldest way (pre-CSS) is to use a <br clear="all"> element. Besides the fact that the HTML "clear" attribute has been deprecated, that's really a misuse of that element anyway. Several <div class="clear"></div> or <div style="clear:both;"></div> elements sprinkled throughout a page is another common sight. Some people (including me) argue that adding extra elements, muddying the nice clean markup, to just fix a presentational (or stylistic, if you prefer) issue is a practice to be avoided. So what are the alternatives?

"Float Nearly Everything"

The simplest one is the "float nearly everything" technique. If you float the container element, then it will automatically grow in height with its floated descendants. I often use this approach on the page header container and the wrapper of content columns and then give the footer "clear:both".

The Aslett/PIE Technique

Another, albeit more complex, (and my second favorite) approach is the Aslett/PIE technique. (Here's a second article on it.) These days, you can use a cut-down version of the code for it, if you are not supporting IE5.0/Win and IE5/Mac. (In the interest of brevity, I won't explain the intricacies of how it works here, but if you have any questions, feel free to ask.)

.clearfix:after { /* for non-IE browsers and IE8+ */
  content:".";
  display:block;
  clear:both;
  height:0;
  visibility:hidden;
}
/* the next two rules for IE6-7 must be separate and be in this order */
.clearfix {display:inline-block}
.clearfix {display:block}

Or, if you prefer this:

.clearfix:after { /* for non-IE browsers and IE8+ */
  content:".";
  display:block;
  clear:both;
  height:0;
  visibility:hidden;
}
*:first-child+html .clearfix {min-height:1px} /* for IE7 */
* html .clearfix {height:1%} /* for IE6 */

I rarely actually apply that "clearfix" class to any elements. Typically, I add more selectors (e.g. "#nav:after, .container:after, .clearfix:after"), so that I can target elements that already have a class or ID.

The Overflow Control Technique

In 2005, Paul O'Brien discovered a new, simpler approach: "overflow:auto" or "overflow:hidden" will cause an element to contain floated descendants (assuming it doesn't have a specified height). It's clean and simple and definitely demonstrates his impressive level of expertise. (I've learned a great deal from him over the last few years.) However, I, for one, prefer not to hide overflow usually. Also there is a second unexpected side-effect that can also occur in some browsers.

Odd Side-effect of hiding overflow

The strange side-effect that can occur with the overflow property happens when a floated element is next to an element that has "overflow:auto" or "overflow:hidden" and has a margin on the same side as the float. The (left or right) margin will be doubled in Firefox 1-2, Safari 1.2+, Google Chrome, and Opera 9.5-10.1. Here's a little live demo: (The four blue boxes will not be the same width in the aforementioned browsers.)

right-floated element
a box that has overflow:hidden and a right margin to allow room for the floated element
a box that has overflow:hidden and a right margin to allow room for the floated element
a box that has overflow:hidden and a right margin to allow room for the floated element
a box that has overflow:hidden and a right margin to allow room for the floated element

There aren't any comments on this blog entry yet.

Login or Register to post a comment