Like the “float quirk”, the “float flag” problem is by no means limited to images inside divs. It is, however, encountered most often with those elements, so that will be the example I use here.

Take most any element – in our example, we’ll use a div. Place a border on it. Put another element – ideally, something with a significant height, such as an image - inside the first, and float the inner element.

You would expect the border of the outer element to fully enclose the inner floated element. You’d be wrong.Float flag problem screenshot

Why does this happen? Put very simply, floated elements do not contribute to the implied height of elements that contain them. The moment you float something, the height added by that element to its container disappears.

Under most circumstances, this is actually not a problem: there is usually plenty of non-floated content to “buffer” the container out and enclose everything. But when text content is paltry, or if the floated content is relatively large in size, and you have a border or background to the container that would draw attention, this “float flag” problem appears.

The immediate response of many front-end developers is to set a height on the containing element that allows enough room for the floated element. But that immediately breaks one of the rules that we discussed regarding the div element, and leads to a entire set of new problems as soon as the content changes in any way.

Essentially what we need is a way of making sure that there is something beneath the floated element, something that is not floated itself. That way the containing element will make itself tall enough to contain that bottom element, and thus also contain the float.

There is one simple solution that will work for all modern browsers: set the overflow property for the containing div to a value of hidden. That is, we apply a class of clearfix to the div, and in our CSS write:

div.clearfix {
	overflow: hidden;
}

The code is somewhat counter-intuitive – the overflowing content is not hidden at all – but it does work.

Older browser solutions

If this doesn't work for your targeted browser, we need to get something under the floated element.

We actually have some CSS that accomplishes that, discussed in an earlier entry: clear. If our floated element is to the right, and if we make any kind of content inside the container that has a style of clear: right, that content has to be beneath the floated content, just as our earlier float quirk solution for images demonstrated.

Once designers see this solution, most are happy to shove any content in the container, clear it and move on. But this is inelegant: not only would we have to repeat this procedure every time we encountered this problem, but adding content or markup to solve a presentation problem is a Bad Thing. (This also directly addresses those of you who would force <br> elements, empty paragraphs, &nbsp’s and all sort of other abominations into code in order to get “extra space”. None of it is necessary, easily adjustable, semantic or elegant.)

What we want is a way of automatically generating something just before our <div> closes, something that doesn’t involve extra markup. We have just such a tool, in the pseudo-selector :after.

Under the assumption that there is the potential for multiple divs on any page to have this issue, we will make this a class:

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

An example of the markup to which this CSS might be applied:

<div class="clearfix">
	<img src="tree-in-winter.jpg" alt="Tree In Winter" style="width: 375px; height: 500px; float: right; padding: 1em; 1px solid grey;" />
	<blockquote>
		<h4>Self-Pity</h4>
		<p>I never saw a wild thing
		<br>sorry for itself.
		<br>A small bird will drop frozen dead from a bough
		<br>without ever having felt sorry for itself.
		<cite>D. H. Lawrence, 1929</cite>
	</blockquote>
</div>

So what did we do? You can see from this example that the :after pseudo-selector really isn’t really “after”: more accurately, it should be called “last thing added inside the element”.

We’ve made the generated space block, so it appears on its own line. We’ve cleared it, on both sides, so it doesn’t matter on which side the last floated element appears: clear: both will handle both left and right.

We could leave things here, but if you found that you needed to use a period, we really should hide all traces of our sneaky fix. We can’t change the display of our period – that’s already set – but we can alter its visibility:

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

Now the period is no longer visible. But as you may have discovered in the simple CSS gallery example, making something hidden still leaves the blank space the element occupied on the page. We can’t use the trick we used then – using position: absolute – because we want to keep the period exactly where it is. How then can we remove every sign of it, yet still leave it in place to solve our problem?

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

Float flag fixed screenshotThat truly hides the period. Now there is no contribution to the height of the div from our period, yet it still remains in place.

Making the CSS Rule Universal

We’ve created this trick as a class, so it can be applied to as many divs as you wish. If you wanted to use this technique universally, you could rename the selector to simply .clearfix. Dropping the preceding div in the selector would enable you to apply the clearfix class to any element, not just divs.

But what if the element you wanted to use the clearfix class on already had a class applied? In that case, you could use a little-known but very helpful technique that allows you to apply two classes at once.

Let’s say that your div had a class called .candyland applied to it.

<div class="candyland">
	<p>Candyland is a happy place…</p>
</div>

Let’s also assume that you have a floated element inside the div, one that causes the problem we have been discussing. You want to keep the .candyland class but also apply .clearfix. Modifying the class attribute value of the div to include both will provide the solution:

<div class="candyland clearfix">
	<p>Candyland is a happy place…</p>
</div>

Technically, you can use this trick to simultaneously apply as many classes as you wished to an element. So long as they have a space between them, each word in the class attribute value will be assumed by the browser to be a separate reference, and their associated styles will be conjoined in the appearance of the element.

Photograph by Santo Rizzuto, licensed under Creative Commons

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.