Skip to main content

How to combat float leakage

Submitted by helen on Sunday, July 11, 2010 - 22:53; Modified on Thursday, August 25, 2016 - 15:33

You've probably encountered the scenario at some point: you have a container block with automatic or percentage dimensions and an overflow:visible (the default value for overflow), and you have two elements inside the container, one of which is floated. You will notice that the content outside of your container will be floated, as if the container wasn't there. And the problems continue because, if you apply a background to your container, your container will appear to be only as high as the non-floated element(s) inside of it. Let's take a look at this effect:

Float leakage in action

Example

In the example below, we have a container called floatExample1 which has a background-color of #FC6, and inside this we have two images, which have been converted to block elements. As you can see, our page renders as if the container doesn't exist. This is obvious by the paragraph below floatExample1 floating next to the images and our background-color not displaying.

It is worth noting that, had the images been inline and not block (which, by default, they are), this issue would not arise. This is because inline elements do not require floating, as they natively sit next to each other, provided there is enough space to accommodate them. The issue only crops up when dealing with block elements floated next to each other.

CSS Code:


#floatExample1 {
	background-color:#FC6;
}

#floatExample img {
	float:left;
}

#testCaption1 {
	font-size:120%;
	font-style:italic;
}

HTML Code:


<div id="floatExample1">
    <img src="../images/chris-redfield.jpg" alt="Chris Redfield from Resident Evil 5">
    <img src="../images/leon-kennedy.jpg" alt="Leon S. Kennedy from Resident Evil 4">
</div>
<p id="testCaption1">This text is supposed to be underneath floatExample1, but it is not. It is, in fact, floating next to the images.</p>

XHTML Code:


<div id="floatExample1">
    <img src="../images/chris-redfield.jpg" alt="Chris Redfield from Resident Evil 5" />
    <img src="../images/leon-kennedy.jpg" alt="Leon S. Kennedy from Resident Evil 4" />
</div>
<p id="testCaption1">This text is supposed to be underneath floatExample1, but it is not. It is, in fact, floating next to the images.</p>

Result:

Chris Redfield from Resident Evil 5Leon S. Kennedy from Resident Evil 4

This text is supposed to be underneath floatExample1, but it is not. It is, in fact, floating next to the images.

Images © Capcom

Disaster! floatExample1 doesn't appear to exist, and the float on the last image has escaped and is causing the captionExample to float next to it.

What's going on?

This behaviour is a deliberate consequence of floats, as floats are not part of the flow of the page. If you place a float within a container that doesn't have set dimensions and a has an overflow of visible (the default value for overflow), the container won't be aware of the float and will act as if it doesn't exist. This is typically where we clear the float, using the clear property on the first element that we don't want to be floated. But what if you want your container to render around the float? How do you accomplish that?

Combating float leakage

The solution to preventing floats from leaking out is to apply overflow:auto to the parent element or to give it a set width and height (a width and height that isn't auto or percentages); if you still support IE6, you will also need to apply height:100% to the container. The overflow:auto method works because the overflow property tells the user agent whether to clip content that overflow the containing block. Setting an overflow:auto forces the container to stretch to fit what's inside of it.

CSS Code:


#floatExample2 {
	background-color:#FC6;
	overflow:auto;
}

#floatExample2 img {
	float:left;
}

#testCaption2 {
	font-size:120%;
	font-style:italic;
}

HTML Code:


<div id="floatExample2">
	<img src="../images/chris-redfield.jpg" alt="Chris Redfield from Resident Evil 5">
	<img src="../images/leon-kennedy.jpg" alt="Leon S. Kennedy from Resident Evil 4">
</div>
<p id="testCaption2">This text is supposed to be underneath floatExample2...and it is!</p>

XHTML Code:


<div id="floatExample2">
	<img src="../images/chris-redfield.jpg" alt="Chris Redfield from Resident Evil 5" />
	<img src="../images/leon-kennedy.jpg" alt="Leon S. Kennedy from Resident Evil 4" />
</div>
<p id="testCaption2">This text is supposed to be underneath floatExample2...and it is!</p>

Result:

Chris Redfield from Resident Evil 5Leon S. Kennedy from Resident Evil 4

This text is supposed to be underneath floatExample2...and it is!

Images © Capcom

Now that we have the overflow:auto on the floatExample2 container, it is being rendered...as is evident by the lovely orange background. The float on our last image is now contained and doesn't leak out.

If the container isn't necessary, what do you do?

If you have a container around an element, but it isn't serving a purpose, you might as well delete it. But, if you delete your container you will find that the float on your last element will now be free to wreak havoc on your page. So, how do you stop floats from messing up a page if you don't want to use a container to hold them in? Simple. You use the clear property, mentioned above.

Example of clear:left

The example above doesn't really need a div surrounding it, so we'll remove the container and apply a clear:left to testCaption. The clear:left clears all floats to the left of testCaption.

CSS Code:


.floatEx {
	float:left;
}

#testCaption3 {
	font-size:120%;
	font-style:italic;
	clear:left;
}

HTML Code:


<img src="../images/chris-redfield.jpg" alt="Chris Redfield from Resident Evil 5">
<img src="../images/leon-kennedy.jpg" alt="Leon S. Kennedy from Resident Evil 4"> 
<p id="testCaption3">This text is supposed to be underneath the images...and it is!</p>

XHTML Code:


<img src="../images/chris-redfield.jpg" alt="Chris Redfield from Resident Evil 5" />
<img src="../images/leon-kennedy.jpg" alt="Leon S. Kennedy from Resident Evil 4" /> 
<p id="testCaption3">This text is supposed to be underneath the images...and it is!</p>

Result:

Chris Redfield from Resident Evil 5Leon S. Kennedy from Resident Evil 4

This text is supposed to be underneath the images...and it is!

Images © Capcom

Our images can now be floated next to each other, without the need for a container, and they will no longer screw up our page. If you'd like to know more about the clear property, check out How to clear floats with the CSS clear property.