Understanding the CSS Float Property

I want to take a moment today and talk about CSS floats. They’re used everywhere in modern web design, from navigation bars to building CSS columns and dozens of techniques in between. However, despite their prevalence, not everyone understands exactly how they work, or what the repercussions might be from using them. So let’s remedy that. You can see all the examples from this article here.

CSS Float Basics

Floated elements are a different beast than anything else in CSS. Floats are technically block-level elements, but they behave like inline elements in that they often don’t exist on a line of their own — the rest of your content will try to flow around a floated element.

the normal document flow, with an image appearing above a paragraph

Floated elements exist outside the normal document flow, which is a fancy phrase that basically says that the order an element appears in the source code determines where it should appear on the final rendered page (see above). Floated and positioned elements are both outside the normal document flow. But floats don’t behave like a regular positioned element.

An absolute or fixed positioned element leave the document flow entirely and sit on top of the normal document, and the space that would have been occupied by that element in the normal document flow is closed. Relatively positioned elements also leave the normal document flow, but the space they took up in the document isn’t closed up: it stays open and in the same spot the element originally sat, regardless of where the element moves.

Floats are different. They leave the document flow and the space they take up is reserved like in a relatively positioned element, but that space moves with the element. The normal document flow then does what it can to flow around that element. If the content following the float will fit beside it, it will do so.

You have two real options with floats: left, and right. The floated element will then move as in that direction as far as it can within its containing element. The content flowing around it can be held at bay by margins, padding or borders on the float.

Working With Floats

So let’s start playing around with floats. We’ll use an example that often throws people for a loop. Let’s say you have a div which contains an image that you plan to float, plus a paragraph of descriptive text that you want to flow around the element. Our HTML might look like this:

1
2
3
4
<div class="container">
	<img src="anything.jpg" class="float" />
	<p>This is my descriptive paragraph.</p>
</div>

In this example, we’ll give our container and the image a border in addition to floating our image, so we can see how they’re behaving. Here’s our CSS:

1
2
3
4
5
6
7
8
.container {
	margin: 1em 0;
	border: 2px solid red;}
.float {
	float: left; }
img {
	border: 2px solid green; 
	margin: 0 .5em 0 0; }

So what’s the result? Something that looks like this:

a css float escaping its container

You can see this live on our example page, as well.

Woah. Unless you’re an experienced float-tamer, this is probably not the result you were expecting or looking for. And it isn’t a bug of any sort. According to the CSS spec:

[F]loating elements can overlap with the margin, border and padding areas of other elements … when the floating element is wider or higher than the element it is inside.

In short, any time your floated element is larger than its container, it will appear to overflow that container. I say “appear” because, as we established earlier, floats exist outside the normal document flow like positioned elements. They’re not contributing to the height of their container at all. The height of the container in our example is being decided by the paragraph’s contents.

So how do we ensure that our float stays within our container? There are two good options.

The first option is to use a clear, which is a CSS property that forces elements to not flow around floats. So if we place a clear somewhere after our floated element in our container, our container will be forced to compensate for the space the cleared element is taking up. And since our cleared element is below our float, it compensates for the float’s height as well:

a css float being cleared by a paragraph with a clear tag

Of course, that requires using an additional element in our HTML — one that may or may not have any semantic value. But there is another alternative that not everyone realizes: a floated element inside another floated element determines that float’s size!

I realize that might sound like gibberish. Let’s go back to our example code, but instead of just floating our image, let’s float the container div as well. As you can see on the example page, here is our result:

a css float containing another css float

Much nicer. And probably closer to what we were expecting, too.

Note that I’ve also specified a width on the container when I floated it: floated elements should always have a width, or browsers may determine their widths differently. Technically speaking the width of the container should be as big as the largest contained element, but when we’re dealing with text that gets complicated… would the largest element be the longest sentence or the longest word? Images are an exception to this rule, because images have an implied width.

So now you hopefully have a better understanding of what floats are actually doing, and how to use them in your work. For more on floats and positioning, see the articles below or visit the table of contents.

8 Comments

  1. On March 19, 2010
    3:51AM

    ivoserrano said:

    another solution!!!

    .container {
    margin: 1em 0;
    border: 2px solid red;
    height= 1%;
    overflow hidden;
    }

  2. On March 19, 2010
    3:56AM

    Brett Aquila said:

    The issue I’m having is that I use background images for my heading tags (H3 specifically) throughout the body of my articles. When I float an image and a heading tag winds up next to it, the text within the heading floats around the image, but the background image does not – it continues all the way across the content div underneath the image – which is simply no good for this type of background image.

    I can use margin on the heading tag itself to fix this problem completely, but I can’t just insert new images or move images without going back and making sure that none of the headings are alongside the floated image. I’ve actually gone to a fixed width site from a flexible width for this reason – there’s no way to know which headings will wind up next to floated images on different size screens without checking every resolution, and even then I couldn’t use margins on the heading tags to compensate for all resolutions – you only need margin if the heading winds up next to a floated element – sometimes it will, sometimes it won’t.

    Oh, and this exact same thing happens with – the styling of the blockquote continues behind the image, but the text flows around it.

    I thought you’d find this to be an interesting example and maybe you have a thought? Here’s the url to a typical article – http://www.bigrigdriving.com/2010/truck-driver-safety/cargo-theft-increasing-highways-are-getting-more-dangerous-for-truckers

  3. On March 19, 2010
    11:20AM

    Wordpress Themes said:

    These are the steps I always follow in order to make sure my floats work well.

    1. Always clear browser margins and paddings:

    *{margin: 0; padding: 0;}

    2. Make sure your floated elements are withing another floated elements.

    Using a Wrapper Div to center your page and than a floated container div inside to hold the content normally does the trick

    3. Keep a clear class in my Stylesheet in case I need it:

    .clear{ clear: both;}

  4. On March 26, 2010
    1:02PM

    Langel said:

    Woah. All this time I have been struggling with clearfix and I could have simply nested a float in a float?!?

  5. On April 12, 2010
    5:30AM

    Abhijit V. Chaore said:

    Thanks for the useful tips.

  6. On May 30, 2010
    3:42AM

    rohnn said:

    @ivoserrano
    Aggreed 100%. Use of overflow:hidden

    @WP Themes
    1 – you should check about a more advanced reset.
    This *{margin: 0; padding: 0;} is far to demanding for the browser.
    2 – floats within float : You end up having every single block in you page floated. I don’t believe it is a correct approach even if it works.
    + you add a floated container just to hold your content. This is some unnecessary html.
    3 – .clear{clear:both} is ok, but it has some issues as you have to use a empty div. Best thus use a div containing a nbsp; and add to you clear; reseter for font size & line height. Anyway, if you float within float, I suppose this clear class is not needed.

  7. On June 05, 2010
    3:58AM

    Pedro said:

    Rob, thank you so much for explaining this. It helped me solve one of the last things I needed to format correctly on a client’s website.

    All the best.

  8. On June 05, 2010
    8:23PM

    Michael Tuck said:

    That float-within-a-float is a nifty little technique, and one I did not know. Ivo may have been referring to the technique outlined on this page, which apparently originated with my SitePoint buddy Paul O’Brien:

    http://www.quirksmode.org/css/clearing.html

2 Responses Elsewhere

  1. Plaveme ve floatech | Tomáš Pavelka said:

    [...] na CSSNewbie se touto problematikou zaobírá a nakonec uvádí velmi pěkné a jednoduché řešení, bez [...]

Leave a Comment