A List Apart

Menu

CSS Floats 101

by Published in CSS, HTML, Layout & Grids64 Comments

The float property is a valuable and powerful asset to any web designer/developer working with HTML and CSS. Tragically, it can also cause frustration and confusion if you don’t fully understand how it works.

Issue № 325

Also, in the past, it’s been linked to some pretty nasty browser bugs so it’s normal to get nervous about using the float property in your CSS rule sets. Let’s calm those nerves and ease that frustration. I’ll show you exactly what the float property does to your elements and how incredibly useful it can be once you master it.

We see floats in the print world every time we pick up a magazine article with an image on the left or right with text flowing nicely around it. In the world of HTML/CSS, text will wrap around an image with the float property applied to it, much like in a magazine layout. Images are just one of the many use cases for the float property: we can also achieve the popular two-column layout using floats. In fact, you can float just about any element in your HTML. By learning and understanding float property basics, along with position property basics, you will be able to achieve any layout with confidence.

The definition

Let’s start with the definition of a float. According to the W3C:

A float is a box that is shifted to the left or right on the current line. The most interesting characteristic of a float (or “floated” or “floating” box) is that content may flow along its side (or be prohibited from doing so by the “clear” property). Content flows down the right side of a left-floated box and down the left side of a right-floated box.

The float property has four values that we can apply to it: left, right, inherit, and none. Each value is pretty self explanatory. For example, if you assign float: left to an element, it will move to the left-most boundary of its parent element. The same idea applies if you were to assign float: right; to an element. That element would be sent off to the right-most boundary of its parent element. The inherit value tells an element to inherit the float value of its parent element. The value none is the default value and tells an element not to float at all.

Here is a simple example like the magazine reference above, Example A and the corresponding markup:

img { 
	float: right;
	margin: 10px;
}

How floats behave

Nothing too complex, but still pretty cool right? Child’s play you say. Ok, well before we get into the part where floats usher in a world of bacon-loving unicorns, let’s back up for a second to talk about what’s actually happening here. In the web world, our HTML is bound by some rules, in particular, the normal flow. In the normal flow, each block element (div, p, h1, etc.) stacks on top of each other vertically, from the top of the viewport down. Floated elements are first laid out according to the normal flow, then taken out of the normal flow and sent as far to the right or left (depending on which value is applied) of the parent element. In other words, they go from stacking on top of each other to sitting next to each other, given that there is enough room in the parent element for each floated element to sit. This behavior is crucial to remember as you build your websites.

Let’s look at a few more examples. In Example B, there are three blocks without the float property applied:

.block { 
	width: 200px;
	height: 200px;
}

Notice how they stack on top of each other? This is the basic concept of normal flow. Here is the same example again, but this time the blocks are all floated in Example C:

.block { 
	float: left;
	width: 200px;
	height: 200px;
}

Now the blocks are sitting side by side. Great, we’ve got that figured out. But what about that part where I said “given there is enough room in the parent element for each floated element to sit?” I thought you’d never ask. Let’s take our last example and increase the box count five fold. The parent element in this example is the body of our document. Notice that depending on the size of your browser window (and subsequently the parent element body), the blocks drop to a second row, because there is not enough room for all of them to sit side by side. As you resize your browser window to allow more room, you’ll see the blocks rearrange themselves. Try it for yourself, in Example D.

In the clear

The float property has a step-brother, clear. The two complement each other in a way that should make you a happy coder. As you may recall, a floated element is first laid out according to the normal flow, then removed from the normal flow. This means that every element that follows a floated element will behave contrary to what you expect. This is where I suspect we might start to get into trouble. Let’s look at a quick example with our blocks again. In Example E, I am going to float two blocks (pink and blue) and directly after those, not float two more blocks (green and orange). Here is the HTML and CSS for Example E:

<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green"></div>
<div class="block orange"></div>
.block {
	width: 200px;
	height: 200px;
}
.float { float: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }

How do you like that green block? Oh wait, where is it? It’s there, right underneath the pink block. The pink and blue blocks are both floated and behaving as we would expect, sitting side by side. Since they’re removed from the normal flow however, the green and orange blocks act as if they’re not even there. That is why our green block is hidden undereath our pink block. So how do we make our green block show up again? Enter the clear property.

The clear property has five values available: left, right, both, inherit, and none. Assigning a value of left says the top edge of this element must sit below any element that has the float: left property applied to it. The same concept applies for the right value—the element must sit beneath any element that has the float: right property applied to it. Using the both value tells our element that its top edge must sit below any element floated either left or right. The inherit value takes on the clear property from its parent element, while the default value none behaves as you would expect. Arming ourselves with this knowledge, let’s look at Example E2. This time we’ll clear our two floats by applying the clear property to our green block. Our slightly modified code looks like this:

<div class="block pink float"></div>
<div class="block blue float"></div>
<div class="block green clear"></div>
<div class="block orange"></div>
.block {
	width: 200px;
	height: 200px;
}
.float { float: left; }
.clear { clear: left; }
.pink { background: #ee3e64; }
.blue { background: #44accf; }
.green { background: #b7d84b; }
.orange { background: #E2A741; }

By assigning a clear: left property value to our green block, we’ve told it to act as if the pink block is in the normal flow of our document, even though it has been removed, and to sit below it. This is an immensely powerful property; as you can see, it helps bring our non-floated elements back into the normal flow, a behavior that we tend to expect by default. That said, knowing and understanding both the float and clear property really starts to open some creative doors when you write your HTML and CSS.

Using floats for layouts

Let’s cover layouts. This is where the float property is incredibly useful. We can achieve the traditional two-column layout in a variety of ways; most of them use one or two floated elements. Let’s take a look at a simple example: a two-column website with the content area on the left, navigation on the right, and a header and footer area to cap it off. For the sake of this article, we’re only going to look at the code related to the floated elements. Here’s Example F:

#container {
	width: 960px;
	margin: 0 auto;
}
#content {
	float: left;
	width: 660px;
	background: #fff;
}
#navigation {
	float: right;
	width: 300px;
	background: #eee;
}
#footer {
	clear: both;
	background: #aaa;
	padding: 10px;
}

Ok, let’s talk about what’s going on here. Our containing parent is aptly called #container. This holds our floated elements in place. If we didn’t have it, our floated elements would shoot out to the far left and right of the viewport (our browser window). Next, we have #content and then #navigation. These are our floated elements. We sent #content to the left, and #navigation to the right, to achieve our two-column layout. I’ve defined a width for each, so that they fill our entire parent container. Finally, we have the #footer, on which we’ve set the clear property. As we know from before, this clear property brings the elements following any floated elements back into the normal flow. In this case the #footer has the value both assigned to it, causing our #footer to sit below both the #content and #navigation elements.

What would have happened had we forgotten to assign the clear property to our footer? Take a look in Example G.

Our #footer has slid up underneath the #navigation. This is happening because there is room underneath the #navigation for the #footer to fill, and given the normal flow that we work within, this is actually the correct behavior. But it’s definitely not what we’re looking for, is it? You can start to see the interaction between the float and clear property and how they complement each other so well.

If you have obsessive compulsive disorder, like I do, you may notice that back in Example F there are unequal heights on #content and #navigation; there are several ways to address that, but that’s out of this article’s scope. I highly suggest reading Faux Columns by Dan Cederholm to learn how to make the heights appear to be the same, no matter what the content.

Float first

So far we’ve seen some pretty straightforward examples that don’t create many headaches. There are, however, some gotchas that we have to watch for when working with the float property. Surprisingly one of the biggest gotchas is not with the CSS but rather with the HTML itself. Where you place your floated element in your HTML can cause different results. Take a look at Example H.

Here we have a nice small-ish box that has an image floated on the right and some text surrounding it. Our CSS is basic:

#container {
	width: 280px;
	margin: 0 auto;
	padding: 10px;
	background: #aaa;
	border: 1px solid #999;
}
img {
	float: right;
}

Our parent element, #container has a narrow width keeping our floated element, the img, within its bounds. Our HTML looks like so:

<div id="container">
	<img src="image.gif" />
	<p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p>
</div>

This basic concept gives us the desired result, but what if we took this same example and rearranged the HTML just slightly? In Example I we’ll move the img to come after our paragraph of text:

<div id="container">
	<p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p>
	<img src="image.gif" />
</div>

Our results are less than desirable. Our image is floated to the right, but it’s no longer in the top corner where we wanted it, falling instead underneath our paragraph; worse yet, it seems to be sticking out of the bottom of our #container parent element. What is going on? First, a rule that I have found that works nicely for my layouts is float first. That is, in my HTML, I almost always place my floated elements first in the markup, and before any non-floated elements that my float will interact with, such as the paragraph in the example above. Most of the time, this gives the desired result. Second, the reason that the image is seemingly sticking out of the bottom of our #container element has to do with something called collapsing. Let’s talk about what collapsing is and how we can best address it.

Collapsing

Collapsing is when a parent element that contains any number of floated elements doesn’t expand to completely surround those elements in the way it would if the elements were not floated. In Example I above, our parent element, #container, collapsed as if the floated img element wasn’t even there. This is not a browser bug, but rather an expected and proper behavior. Since floated elements are originally calculated in the normal flow and then removed, the #container element doesn’t consider it within its bounds and therefore acts as if it isn’t even there. As a note, Eric Meyer has a wonderful article on this topic called Containing Floats that goes into much more depth and is a highly useful resource. The good news is, we can remedy this problem in a myriad of ways; if you’re guessing that it has to do with the clear property then you’re on the right track.

One of the most common ways to fix a collapsed parent element is to place an element with the clear property after our floated element. This will cause the parent to begin reflowing after the floated element. It may be easier to show this in action. Look at the HTML for Example J which is the same as our previous example, but with one extra element added:

<div id="container">
	<p>This is some text contained within a small-ish box. I'm using it as an example of how placing your floated elements in different orders in your HTML can affect your layouts. For example, take a look at this great photo placeholder that should be sitting on the right.</p>
	<img src="image.gif" />
	<div style="clear: right;"></div>
</div>

By placing a div with an inline style of clear: right we’ve managed to get our #container to clear our floated image by having it recalculate its height now that there’s an element sitting below it. While this solution works, it may not be the most elegant because we had to add extra markup to our document. It would have been sexier to handle this with CSS. There are a few ways to do that, so let’s take a look at one of them right now.

Consider this example, a parent element containing three floated images. Our HTML looks like this:

<div id="container">
	<img src="image.gif" />
	<img src="image.gif" />
	<img src="image.gif" />
</div>

and our CSS looks like this:

#container {
	width: 260px;
	margin: 0 auto;
	padding: 10px 0 10px 10px;
	background: #aaa;
	border: 1px solid #999;
}
img {
	float: left;
	margin: 0 5px 0 0;
}

When you look at this in action, you’ll quickly realize that our parent element is not containing our floated images. Again, this is expected because floated elements are removed from the flow, so according to our parent element, #container, it’s empty. Take a look at this in Example K.

Now let’s try to remedy this with CSS instead of adding extra HTML markup to our document as we did before. There is a method that allows a parent element to clear itself of any floated elements inside it. It uses a CSS property called overflow with a value of hidden. Note that the overflow property was not intended for this type of use, and could cause some issues such as hiding content or causing unwanted scrollbars to appear. You can read more about how it came to be and some of its caveats here and here. For our example however, we’ll apply the overflow: hidden property to our parent element, #container:

#container {
	overflow: hidden;
	width: 260px;
	margin: 0 auto;
	padding: 10px 0 10px 10px;
	background: #aaa;
	border: 1px solid #999;
}

Our results are in Example L. Pretty cool right? Another method which gives similar results with fewer caveats uses the pseudo selector :after. Using our example, the code is:

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

Here, the CSS is placing a new element after our #container element that has some content in it (in this case, a period), and setting it to be hidden with no height. You can find a very thorough and detailed overview of this technique at Position is Everything.

Finally, Eric Meyer explains a third way to tackle this problem in his article referenced above, Containing Floats. According to the CSS Spec 2.1:

a floated element will expand to contain any floated elements that descend from it.

So in this case, floating our container element would cause it to contain our image and paragraph the same way as the methods described above.

Ultimately all of these solutions are doing the same thing. They are making the parent elements respect the flow of their floated children. Each one has its merits and usefulness. You should learn about each and then apply the ones that work best for your given situation.

Things that may cause rapid hair loss

Believe it or not there are a few browser bugs that floated elements can bring on, such as the double margin bug and the 3px Text-Jog. Both of these are outside this article’s scope, but rest assured they are both easily remedied if you want to support older browsers.

Conclusion

Using the float property can pad your layout technique toolbox in some very cool and responsive ways. Understanding how they work and the principles by which they behave will give you a solid foundation for using floats effectively.

About the Author

64 Reader Comments

Load Comments