Back to the article

ez-css Putting the 'less' in table-less layouts. css-101 logo

This is a demo page that compares 4 different methods to contain floats without structural markup

  1. .FnE
  2. .clearFix
  3. .pmob (Paul O'Brien's)
  4. .newBFC

The exercise is to create a two column layout, making sure both columns contain floated elements.

Markup and CSS for the boxes on this page

Markup

<div>
 <div class="header">
  Header: Lorem ipsum...
 </div>
 <div class="sideBar">
  Side bar: Lorem ipsum...
  <img src="image.jpg" alt="A floating Image" />
 </div>
 <div class="content">
  Content: Lorem ipsum...
  <img src="image.jpg" alt="A floating Image" />
 </div>
 <div class="footer">
  Footer: Lorem ipsum...
 </div>
</div>
CSS rules

* {margin: 0; padding: 0;}
body {padding: 20px;}
div {border: 3px double red; margin: 20px; padding: 10px;}
div.header,
div.footer {padding: 5px; background: #ececec;}
div.footer {clear: both;}
div.sideBar {float: left; width: 150px; padding: 5px; background: #9cf;}
div.content {padding: 5px; background: #ffc;}
img {float: left;}

Things to notice from the above:

To better see what's involved, compare the display of the different boxes within the same browser and then compare these boxes using the different browser windows side-by-side (i.e. IE versus Firefox).
You can also use the button above the boxes to switch from widthless boxes to fixed width boxes. An extra button shows in IE Win (gte 5.5) to let you check if the "content" container has Layout..

Some history first

Out of the box "behavior"

The box below is styled with CSS rules common to all boxes. Note that the image in "content" (yellow box) is not contained while the one in "sideBar" appears enclosed (hence the blue background color showing behind it). No clearing method is applied yet, it is just the construct of the box that makes the "sideBar" contain the floating image. This is because a float always encloses floats (see Visual formatting model, Section 9.4.1). Also, notice that the yellow background shows below the left column which indicates that "content" and "sideBar" are both aligned against the left edge of the parent container.

FYI, IE Mac goes ballistic depending on the font-family used. For example, this test-case demonstrates that using "Georgia" makes floats escape floats! It also shows that using this font-family will make display:inline-block; fail to enclose floats when the box is widthless.

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

Clearing using structural markup (a BR)


<br style="clear: left;" />

To do this, we add an HTML element (see above) in the markup, right before the closing "content" div tag.
It appears that this technique works in most browsers, but not in Internet Explorer Win.

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

Clearing using structural markup (a DIV)


<div style="clear: left;"></div>

We still use a structural element, but this time it is a div instead of a br which proves itself more reliable across browsers.

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

Applying the 4 clearing techniques to the "content" container

We start over with the original markup (clearing br/div are removed).

1. The Float [nearly] Everything method


.FnE {
  float: left;
}

As mentioned earlier, the float property creates a new block-formatting context (see Visual formatting model, Section 9.4.1), so it works nicely with a minimum of effort. The problem is that widthless floats display differently across browsers. Also, note that this technique may require you to style another element; for example "footer" would be misplaced if it was not already styled with clear:both;. That "footer" would get close to the "header", both elements would be wrapped in the red bordered box, but "sideBar" and "content" would display outside of that box.

It is important to notice that here (at least in browsers where the right column does not drop below "sideBar"), the yellow background does not extend across the box, but starts at the right edge of the left column (white background shows below the left column).

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

2. The .clearfix method

This solution makes IE create a new block-formatting context while other browsers clear the floats the "structural way" (see above: clearing with structural markup). For this reason, the layout of "content" will vary across browsers. In non-IE browsers that obey the pseudo-class :after, content of the yellow box flows below "sideBar" while in IE, that yellow box appears against the right edge of "sideBar", its content (text and image) do not flow below it; a white background shows below "sideBar".


.clearfix:after {
  content: "."; 
  display: block; 
  height: 0; 
  clear: both; 
  visibility: hidden;
}
.clearfix {display: inline-block;}
/*\*/
* html .clearfix {height: 1%;} 
.clearfix {display: block;} 
/**/

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

3. The Paul O'brien's method


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

This technique creates a new block-formatting context in all browsers. It relies on overflow (for good browsers) and on having Layout (for IE Win). Unfortunately, the 100% width is not a good fit for our two column layout as most browsers will drop "content" below "sideBar". IE Mac does not drop the right column, but cuts-off text and image.

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

4. The .newBFC method


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

This technique is based on the Paul O'Brien's method, but it includes a few extra declarations so authors do not have to specifiy a width and are able to use the IE "min-height" hack (_height). It also borrows the IE Mac fix from the "clearFix" method.

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

But what if...

Of course we could not expect this to be that easy, right?

Things get interesting if we decide to set a left margin on the "content" container. Then cross-browser compatibility becomes an issue again (note that this issue does not exist if the float property is used to create a new block-formatting context).

Using left margin on content


.content {margin-left: 30px;} 

For Internet Explorer Win, the reference point is the left edge of the parent container. It seems IE is setting a left margin equal to the total width of the left column (border+padding+width). Opera and Safari 2.0 do something really weird, they create some margin on the opposite side of the box. Firefox and IE Mac use the right edge of the sideBar container for reference and create a gutter as wide as the margin value set.

Note that trying to offset the box using margin or border (as shown below) works in IE Mac, but then the container stops enclosing the floats.

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

Cheating with a border


.content {border-left: 30px solid #fff;} 

So the important thing to keep in mind when using this technique is to use border-left instead of margin-left if a space to the left of the container is needed.

Using a transparent border does not really work in IE lt 7 (border is painted black) and Opera (border is painted the same color as the right column's background). So the best way to go is to match the color that would appear to the left of the element as if the margin was properly applied (in this case white, the color of the parent div).

Header:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Content:
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec lacinia fringilla elit. Aliquam eget purus. Cras interdum, elit a luctus pulvinar, nulla eros tempus nunc, in sagittis est dolor et dui. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. A floating image

This work is licensed under a Creative Commons License Creative Commons License.