Wednesday, August 11, 2004

Using :after to clear floats

The example block below demonstrates how to use the :after pseudo-class to clear all floating elements in a block. In this example, the middle block (in this case a <p>) has a :after which will create another block and have it clear.

This is the left floating div
This is the right floating div

I'm normal content within the .p div

The code is pretty straight-forward

<style type="text/css">
.container p { margin: 0; border: 1px solid #ffff00; }

/* this is the middle element */
.container p:after {
display: block;
content: "I want this to clear";
	border: 1px solid #900;
	float: left;
	clear: both;
}
.container {
	border: 1px solid #0f0;
	width: 80%;
margin: 0 auto;
}
		
.left {
	float: left; width: 5em;
	border: 1px solid #789;
}
.right {
	float: right; width: 5em;
	border: 1px solid #aca;
}
</style>
<!-- skip to you body -->
<div class="container">
<div class="left">
This div floats to the left
</div>
<div class="right">This is the right floating div</div>
<p>I'm normal content within the container div</p>
</div>

There are a few things to notice, first, the clearing block is applied not to the container, but rather the middle block. The middle block is denoted with a bright yellow border. The reason that this works is because the :after pseudo-class is still contained within the creating block. In the above example, the clearing block is denoted with a red border. Note: In IE you will not see the red bordered element at all.

Since the height of an in-the-flow block is stretched beyond the height of the floating elements, its container will grow as well. The container, in this example, has a green border.

IE does it wrong anyway

IE does this wrong anyway, so there is no containing floats issues with IE. And since IE ignores the :after pseudo-class, nothin is lost!

The only difference IE will show is that the yellow bordered inner-block will not stretch around all elements

The gotcha

In order for this to work in a layout, you need the content to probably be empty. No problem. Use the following CSS instead:

<style type="text/css">
	.container p:after { 
		display: block;
		clear: both;
		content: " ";
		height: 0;
		overflow: hidden;
	}
</style>

Using the above, the results look like this:

This is the floating div This is the floating div This is the floating div This is the floating div
This is the floating div

I'm normal content within the container div

It's magic! No red bordered element, no content, no gaps.

Thanks to Phrogz for the inspiration.

0 Comments:

Post a Comment

<< Home