logo
Page Affairs

Editing and Web Design

Simple Tips on Containing Floats

Note: this post is from 2009, but continues to remain relevant, despite newer layout options in CSS.

The float property of CSS is a powerful way to lay out the elements of a web page. For example, an image might be floated so that text will wrap around it; or divs may be floated so that they will sit side by side.

When an element is floated, it is “taken out of the document flow”—meaning that the other elements (for the most part) act like it’s not there—and this can cause some unexpected layout results. For example, floats often need to be “contained” to avoid a common problem that is demonstrated below. Fortunately, there are some easy ways to do this.

An Example

Below is an example of a standard div (colored green) that contains two floated divs:

A div floated left

A div floated right

However, the container is only wrapping around the floated inner divs because of a little CSS containing artifice. Without it, we would actually see this:

A div floated left

A div floated right

Yikes! That’s not good (especially if you want the container to display a background image or color); yet this is normal behavior. Because floats are not in the document flow, the containing div does not see them, and so it closes right up. (If it were not for some padding on the containing div, we would not be seeing it at all in the second example.)

So we need a way to make the containing div wrap around its floated contents. Below are some well-known methods.

Firstly, here is the HTML code for the example above, to which the fixes below will be applied:

<div class="contain">
    <div class="left">
    </div>
    <div class="right">
    </div>
</div>

Using overflow: hidden

A simple fix that works in most situations is to add the rule overflow: hidden to the CSS of the containing div, like so:

div.contain {
    overflow: hidden;
}

This is perhaps the easiest way to contain floats. (It is the method used in the first example above.) In some situations it will not work, however—such as when you actually want some content to overflow the container. The following method, in contrast, avoids such problems.

Using clearfix

The “clearfix” method—devised by Tony Aslett and friends—is widely employed, and is probably the best method for containing floats. To use it, firstly add a new class to the HTML:

<div class="contain clearfix">
    ...
</div>

Then add this to your style sheet:

.clearfix:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}

.clearfix {display: inline-block;}

/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */

That code will make the container wrap around its floated contents like a charm. The two /* comments */ at the end for IE Mac are pretty much redundant now, so they can safely be removed if you really want to.

There is another way to use the clearfix method that avoids adding the extra "clearfix" attribute to the mark-up. The container div already has a class value, namely "contain", and the clearfix code can be linked to this instead, simply by changing the word clearfix to contain:

.contain:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}

.contain {display: inline-block;}

/* Hides from IE-mac \*/
* html .contain {height: 1%;}
.contain {display: block;}
/* End hide from IE-mac */

If you wanted to apply the clearfix method to other divs with different classes or ids—such as id="main"—you would expand the code like this:

.contain:after, #main:after {
    visibility: hidden;
    display: block;
    font-size: 0;
    content: " ";
    clear: both;
    height: 0;
}

.contain, #main {display: inline-block;}

/* Hides from IE-mac \*/
* html .contain, * html #main {height: 1%;}
.contain, #main {display: block;}
/* End hide from IE-mac */

… and so on.

Floating the container

A good way to contain floated elements is to float the container as well. This will always work to contain the floats; but it is not always appropriate, such as when the container is a horizontally centered page wrapper. (The wrapper would no longer be centered on the page.)

When floating the container, it is necessary to give it a width to prevent it from shrink-wrapping the contents:

div.contain {
    float: left;
    width: 96%;
}

Result:

A div floated left

A div floated right

Using CSS table display

Another method for containing floats is to use display: table. The downside is that this approach will not work in IE versions 7 and under. Even in proper browsers, we must give the container a width to have our example appear as it did in the first example; otherwise, it will shrink-wrap the floats. (This is not a bug, mind you, but natural table display behavior.)

Here is the CSS code we need:

div.contain {
    display: table;
    width: 96%;
}

Here is the result:

A div floated left

A div floated right

Using inline-block

Similar to the display: table method is the use of display: inline-block. Again, this doesn’t work so well in IE versions 7 and under; and again, a width is needed on the container.

Here is the CSS code we need:

div.contain {
    display: inline-block;
    width: 96%;
}

Here is the result:

A div floated left

A div floated right

Using the clear property

Another way to contain floated contents is to follow the contents with a non-floated element and add clear: both to the CSS. For example, we might add a footer div to the contents of the container:

div.footr {
    clear: both;
}

Here is the result:

A div floated left

A div floated right

A non-floated footer div with clear: both

In this example, clear: left or clear: right could also have been used in place of clear: both. The downside is that a bottom margin needed to be added to the floated divs to stop them touching the footer.

When no such extra div is wanted in the layout, this method can be used on the sly to contain the floats anyway. For example, simply adding an empty div (as highlighted):

<div class="contain">
    <div class="left">
    </div>
    <div class="right">
    </div>
    <div style="clear:both"></div>
</div>

…produces this:

A div floated left

A div floated right

Another such solution is to add something like <br style="clear:both"> in place of the empty div. However, containing floats is an issue of presentation rather than meaning (or “semantics”, in fancy talk), so it is best to avoid adding meaningless divs or other elements like this.

Using position: absolute

Another option for containing floats is to set the container to position: absolute;, though I can’t think of many situations in which you’d want to do this, as setting an element to position: absolute introduces other problems in page layouts. However, it may turn out that you have floated content inside an element that is already positioned absolutely, so you’ll find that the container already wraps around the content!

Here is the CSS code we need:

div.contain {
    position: absolute;
    width: 96%;
}

Here is the result:

A div floated left

A div floated right

Final Notes

I haven’t said much here about issues relating to Internet Explorer versions 7 and under. The overflow: hidden method works in IE7 (as it triggers hasLayout) but not in IE6—though the container will enclose its content if it is given a width. The clearfix method works well with IE, as does floating the container, and adding in cleared divs after the floats works tolerably. As mentioned, display: table is not an option.

There is occasionally a problem with the clearfix method, such as extra space appearing after the containing div. This can be cured by adding font-size: 0; to the clearfix code.

Update—2012

With the merciful demise of older browsers, the clearfix code can be greatly simplified. Here are some more modern examples:

From Thierry Koblentz:

.clearfix:after {
    content:"";
    display:table;
    clear:both;
}

From Paul O’Brien:

.clearfix:after{
    content:".";
    display:block;
    height:0;
    clear:both;
    visibility:hidden;
}

… and also this:

.clearfix:after{
    content:" ";
    display:block;
    clear:both;
}

Acknowledgements & Links

Legacy Comments

Alex M — July 23, 2012

Tommy Olsson gives an example of when overflow: hidden will cause problems. Rather than try to paraphrase, I’ll just quote:

If you have a multi-column layout where the layout order is different from the source order (not uncommon), you’ll run into trouble. This type of layout is usually achieved with a combination of wrapper padding/margins, negative column margins and relative positioning. The problem is that the relative positioning puts the side columns outside the wrapper, and with overflow:hidden they become ... hidden.

BTW, you are not very clear about when font-size: 0 is actually needed.

Ralph Mason — July 23, 2012

Thanks for that, Alex.

Regarding font-size: 0, I’m not sure, but I’m wondering if this is only an issue for FireFox 2. That’s the only browser I’ve seen this happening in, but I’d like to know if it’s still a potential issue in the latest browsers.

I’ve seen that Opera sometimes adds space after a “clearfixed” div unless font-size: 0 is used ... but I’m not sure if that happens with the latest versions.

© Page Affairs, 2008–2024