Hi there, I’m Brian McKinney

Developer, designer, musician, recording engineer. In other words, I like to make things

The best way to clear floats

  • November 6, 2008
  • in css, design, html

When working with HTML and CSS, I always want to find the best technique for solving a certain problem and use it every time. This philosophy can be very frustrating when the solution to certain problems is rather ambiguous, or certain problems can be solved in multiple ways, each with their own drawbacks. Using CSS to clear floats is a great example of a problem with many solutions, none of which is absolutely ideal.

Some background regarding the problem

Clearing floats is tricky business. As any web designer knows, when you float an element within a containing element (such as a navigation column within a content area on a page), the floated element is taken out of document flow. Consequently, instead of the containing element expanding to fit the floated element, it will completely ignore its dimensions. This causes floated elements to be rendered outside of the containing element, which is a major problem if you are interested in maintaining any sort of aesthetic appeal within your design.

There have been a handful of reasonable techniques used to solve this problem in the past, but none of them are without their problems.

The old school way

Originally, many web designers used extra markup to clear floats. Adding an empty div with a class of clear just beneath the element you are floating works like a charm across browsers, but it's messy.

<div id="containingElement">

A bunch of really smooth content.

Some sidebar information

 div.clear {
       clear: both;
  }

It's not that big of a deal to do this once or twice on a page, but consider a long list of items, each containing elements that must be floated. All of a sudden you are adding several empty HTML elements to your page for no reason. It works, but it just feels dirty.

The newer school way

At some point in my lengthy travels across the Internets, I ran across the method of adding the overflow: auto; style rule to the containing element in order to clear the float. I immediately wiped a single tear from my eye and said goodbye to empty divs and structural markup. This works great, as it behaves similarly in major browsers, and it leaves the structural rules in the CSS where they belong (just make sure you use a height: 1%; in IE 6 to give it layout).

Unfortunately, there are some issues that crop up from time to time that make this an imperfect solution. Margin and padding must be adjusted in certain cases, as scroll bars sometimes appear where you don't want them to (you can use overflow: hidden; instead to overcome this or simply adjust your widths and heights to fit properly within the containing box). Additionally, I've experienced issues with disappearing borders in Firefox when using this technique. My main gripe with this technique is that there are situations when you may want to clear a floated item, but not have it's overflow hidden.

An IE specific way

As we all know, IE likes to do things their own way. IE cruelly turns a blind eye to some pretty important standards, while having a penchant for leaving hooks in non-standard places to accomplish the same thing. Case in point: the zoom: 1; property. Adding zoom: 1; to the containing element clears the float in all IE browsers without any strange artifacts. This is extremely handy for taking care of clearing floats with CSS in IE, but we obviously need a solution that works reliably in all major browsers.

Another good way

After some more digging, I found what I view as one of the cleverest and best float clearing techniques. This technique works in all modern browsers that support the :after pseudo-element (this means that IE6/7 don't get it!).

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

The :after pseudo-element inserts a float clearing area just after the content within the containing element. Your floated element is safely cleared in the CSS, and even better, there are no weird bugs or artifacts. The main drawback to using this technique is that it is quite verbose, as compared to the sleeker, sexier overflow: auto/hidden technique. However, this does provide a reliable method to clear floats in all modern browsers without weird artifacts, or hindering your ability to utilize the overflow property.

I almost forgot about that pesky IE 6/7 thing. In order to use this technique and clear the float for IE6/7 we must combine a couple of techniques.

Most likely you already have a conditionally commented style sheet that targets IE6/7 directly. Using that, simply add the zoom: 1; rule to the container of the elements as explained above, so that IE 6/7 will play nicely. Luckily, IE 8 is on the horizon and will support the :after pseudo-element, so at least at some point in the future, IE will support the standards compliant technique and we will be able to do away with this zoom: 1; nonsense..

The best way

This is one of those situations with HTML and CSS where there isn't one true way to accomplish what you want to do. There are drawbacks to both of the standards-compliant methods I've described. This is definitely a circumstance where you'd want to evaluate what you are trying to do, and use the technique that best fits your situation. If you want to use a simple, quick method to clear a float, use overflow: hidden;. It works in most situations. If you want to be absolutely sure that your CSS won't get in the way of your design, use the more verbose method. Both of these techniques keep the design in the stylesheets and out of the HTML content, so you can't lose.

Comments

1 Joshua Works says

You mention the cons to using overflow: auto to clear floats. overflow: hidden works equally well without the side effects and is what I use almost exclusively to clear floats within elements.

Posted at 4:56 p.m. on November 6, 2008

2 Brian Mckinney says

You bring up an excellent point Josh. I should have been a bit more clear about my problems with overflow: auto;. My problem isn't not so much the scroll bars. That can be annoying, but is easily worked around by using overflow: hidden;, as you've recommended. My main problem is that I've noticed some strange behavior with disappearing borders when using this technique. I also think that there are times when you would want to clear a float when you wouldn't want to have overflow: hidden; declared. In that case, you'd definitely want to use the more verbose technique.

That said, your comment got me thinking about the original point of my post, and I think that you are on to something. Using the more verbose method isn't always optimum because you may want to use :after on a floated element to add some visual content, not clear the float. I think I will re-formulate my posting to emphasize that there are situations that both techniques would be handy, and it really depends (like most things) what kind of a situation you are in.

Posted at 3:45 p.m. on November 7, 2008

3 Erik says

The overflow trick also fails when you need content inside the div to extend beyond the borders (ie. a tooltip or some other overlay)... however it is my preferred method as I hate adding extra markup.

Posted at 3:38 p.m. on June 12, 2009

Comments are closed

Comments have been closed for this post.