Web Design 101: Floats

As browsers get better and better, creating layouts with CSS becomes easier and easier. A reliable workhorse in CSS layout options is the float property. Floats are not the only choice when it comes to creating layouts, but they are popular because they survive the unpredictability of designing for various screen sizes, resolutions, and browsers as well—or better—than some of the other choices.

float is not a positioning property in CSS —the only position properties in CSS are absoluterelativefixed, and static—however, when you combine widths, margins, and floats, you have CSS properties at your command that are often more reliable in terms of layouts than any of the available position properties. You can create all sorts of layout arrangements with float, whether or not float is technically a positioning property.

This article will introduce you to the basics of float, explain how to contain a float when the floated element is larger than the size of its container, and give you example layouts created with floats.

In all of the example pages, the CSS rules are in the document head—take a look at the source to see the full set of style rules used in each example. (You may notice that the examples are percentage-width layouts, but you can do the same float exercises with other relative measures such as ems, or with fixed width layouts using px units.)

What is float?

Floats remove elements from the normal document flow and allow text or other elements to wrap around them. A float is the CSS equivalent of what we used to do back in the days when we put HTML attributes such as align="left" or align="right" into elements. As do print designers, web designers need a way to make text flow around an element in a page layout. Floated elements are the solution.

Elements can float to the left or the right of their containers, but not to the top or bottom.

All elements can be floated: images, lists, paragraphs, divs, spans, tables, Flash movies, blockquotes, or anything else in your HTML arsenal. Example 1 shows images with and without the rule img {float: left;} applied—in a nutshell, this is basically what float makes possible. However, when you use other properties with float—we’ll get to them later in this article—you can create columns using float—and when you have columns, you can create a layout.

View Example 1

I mentioned that floats are removed from the document flow. Document flow is simply the order of the content in the document source. An HTML document is read by a browser from top to bottom in the order in which the elements are entered in the HTML source. CSS can be used to change where elements appear in the browser, but that does not change the underlying order of the elements.

To get slightly technical for a minute, a floated element is removed from the normal document flow and shifted to the left or right until its left or right edge touches the left or right edge of its containing block. Other elements that follow the floated element within that containing block then make space for it, behavior commonly described as, “wrapping around it.” The placement of the floated element within the document flow still matters, however, because the wrapping begins with whatever element follows the floated element in the source code. See example 2.

View Example 2

What if the floated element is larger than its container?

The wrapping effect created by a float may present a problem if the containing element, perhaps a div, isn’t large enough to contain the floated element. When this happens the floated element can extend beyond the bounds of its containing element and play havoc with other parts of your page.

I’ll enclose the floated elements in divs, so you can see the containers they are in with borders outlined in the next examples. In example 3, you see a floated image in a div with with the id noncleared. The example uses these two rules:

img {
  float: left;
}
#noncleared {
  border: thin solid #F00;
}

The div containing the image is outlined in red to emphasize the actual size of the floated element’s container.

View Example 3

To prevent content that follows the div containing the overflowing image from continuing to wrap around the floated image, we can use the CSS property clear. The possible declarations for the clear property are clear: leftclear: rightclear: both, or clear: none. Using clear: left or clear: right forces your content past anything floating on the left or on the right, respectively. Using clear: both forces material past anything floating on either side.

I’ll add some new content in a second div (cleverly named cleared) to my page using this rule:

#cleared {
  clear: left;
  border: thin solid #00C;
}

In example 4, you can see the effect of the clear: left rule. The new div does not begin until it has found a spot on the left side of the containing block that is free of other floated content. (The containing block in this case is the body element.)

View Example 4

There are several other methods for clearing contained floats later in the article. For now, let’s look at using float to create a layout.

Can you float a whole layout?

Floats are popular layout tools. float has earned a spot as a beloved CSS property precisely because it is useful for creating layouts.

float is not a positioning property in CSS —the only position properties in CSS are absoluterelativefixed, and static—however, when you combine widths, margins, and floats, you have CSS properties at your command that are often more reliable in terms of layouts than any of the available position properties. You can create all sorts of layout arrangements with float, whether or not float is technically a positioning property.

You can see a simple example of two columns created with float in example 5. Two columns are created by floating a div that is constrained to a width of 70% to the left of the page:

#content {
  float: left;
  width: 70%;
}

The remaining 30% of the page is filled with a second column (actually, another div) that has a margin-left: 75% rule to prevent it from wrapping under the floated column on the left.

When floating any element, you may want to assign a width to it, unless you want the contents to shrink-wrap. In example 5, if the element that is floated to the left did not have a width assigned, the float would shrink down to the width of its content—in this case long lines of text that would overlap the sidebar on the right, but if for example there was just a small image there, the width of the containing floated #content block would be correspondingly narrow.

View Example 5

Notice that the 70% content div and the 25% sidebar div (100% minus the 75% left margin) do not add up to 100% of the width of the page. In the absence of any padding in these example divs, the extra 5% acts as a gutter between the two columns. This would be especially important if the colored borders were removed in the examples. In actual practice, you might opt to use divs that filled 100% of the width, and then give the text some whitespace with margins or padding.

Most page layouts need a header and footer area. Take a look at example 6. It has new 100% divs for a masthead and a footer. Notice that the new #footer div falls immediately under the sidebar div. It’s colored purple so you can see the problem it presents.

View Example 6

You’re probably way ahead of me in realizing that the clear property is what is needed to get this footer to behave. The clear property can be added to the CSS controlling the footer:

#footer {
  background: #EAD5FF;
  border: 1px solid #90F;
  clear: left;
}

The effect of the clear rule is shown in example 7. The footer moves down the page until it finds a spot where there are no floated elements on the left edge of its containing block. (Again, the containing element in this example is the body.)

View Example 7

Want a colored sidebar?

Two-column layouts often have one color background for the content and another color for the sidebar. This can create a problem. Before I explain how to solve the problem, I’ll give you an example of it.

The div borders will be removed to emphasize this example. The sidebar div gets assigned a background color. Take a look at example 8.

View Example 8

The sidebar is merely as large as the content in its div, and the background color does not extend fully down the page. There are many creative and very workable solutions to this problem, including the famous faux columns solution that uses a background image.

I’ll describe one alternate method of solving this problem. It requires wrapping everything on the page in a container div.

The rules in effect for example 9 are:

#container {
  background-color: #DBFFC2;
  width: 90%;
  margin-right: 5%;
  margin-left: 5%;
}
#content {
  float: left;
  width: 70%;
}
#sidebar {
  margin-left: 75%;
}
#masthead {
  background: #FFC;
  border: 1px solid #090;
}
#footer {
  background: #EAD5FF;
  clear: both;
  border-top: 2px solid #90F;
}

View Example 9

In example 9, both the content and the sidebar divs are now light green—both allow the background-colordeclared in the container to shine through. The masthead and the footer, although they are enclosed in the container div, have declared values for background-color that obscure the background-color of the container.

The appearance we want is for only the sidebar to be light green. One more rule will create that effect. Simply make the background-color for the content div white:

#content {
  background: #fff;
  float: left;
  width: 70%;
}

We now have the appearance of two individually colored columns, both of which seem to extend completely down the page. See example 10.

View Example 10

The footer is nested inside the container, so when the footer is set to clear: both, the container stretches down to enclose it.

There is one caveat to using this method. If the sidebar happened to be longer than the content, then the background color of the content div would stop before it reached the footer.

How about three columns?

There are many ways to make a three column layout with floats. The one I’ll show you involves adding another container to the page. The new container, which I’ll give the id innercontainer, will enclose the existing content div and a new div for the third column. The new div will have the id innersidebar.

The #innercontainer will use float: left and a width of 75%. Remember, we have to leave room for the existing sidebar we want to keep on the right:

#innercontainer {
  float: left;
  width: 75%;
} 

Next, make some changes to the rule for the content. It will float: right, so the new div will appear to its left. Again, the dimensions need some adjusting to make room for the new #innersidebar. The content rule is changed to:

#content {
  background: #fff;
  float: right;
  width: 65%;
}

Finally, add the new #innersidebar. It goes in the document source after the content, but before the existing sidebar:


  </div> <!-- end content -->
  
  <div id="innersidebar">
    stuff and things go here
  </div>
</div> <!-- end innercontainer -->
<div id="sidebar">
...

The CSS rule for the inner sidebar is:

#innersidebar {
  float: left;
  width: 35%;
}

I’ve added a black border to the #innercontainer in example 11, so you can see where the new container is.

View Example 11

I’m fond of this solution to the three column layout—it keeps the content first in the source code, which is an aid to both screen-reader users and search-engine spiders. But, it does require two container divs, which adds non-semantic markup to the document. Other three-column layouts often require a trade-off as well.

If you search the Internet for three-column layouts using floats, you’ll find many other ways to use floats. With many of these, you must choose between a slight addition of non-semantic markup, or use hacks. This is because float is not really a positioning property. It’s been adapted into a layout tool out of necessity and frustration with other means of making a reliable columnar layout. If the CSS property display: table ever becomes supported by the majority of browsers, many columnar layout issues will be easier to solve. (The CSS property and value display: table is not the same as the HTML <table> element, which is used to format rows and columns of data.)

Float your thumbs

You can line up a number of floated items side by side to create page displays as diverse as navigation bars and image galleries. I’ll show you how to create a thumbnail image gallery.

I’ll display a bunch of small images in an unordered list. Each list item (li) contains the thumbnail image and a text caption. The normal behavior of list items (being block-level elements) is to move down to begin on a new line for each new item. I ‘ll use float to make these list items display like a resizable thumbnail gallery.

The first step is to assign the whole unordered list an id of “thumb”. This rule removes the bullets and eliminates any default margins:

#thumb {
  list-style: none;
  margin: 0;
}

Next, style the list items. The float rule makes these list items all pile one after another in a horizontal line (like words in a sentence), taking up whatever space the width of the container allows:

#thumb li {
  float: left; 
  display: inline;
  width: 75px;
}

The width: 75px rule forces the caption text to appear under the thumbnail image, because that is the exact width of my thumbnail images. As you can see in example 12, there are several other declarations in the #thumb li rule—the other CSS is simply to make it look a bit nicer.

The two most important rule declarations for the gallery effect are those for float and displaydisplay: inline is included because it eliminates the IE floated double-margin bug. (There’s more about this bug in the Resources section at the end of the article.)

I can put as many thumbnail images and captions as I want in my list, and the layout of rows and columns created will change with the user’s available browser space. To see how it works, look at example 12 and resize your browser window.

View Example 12

(Don’t forget for your real-world thumbnail gallery to include links to the larger versions of your images.)

It’s important to note that these images are all the same height and the captions all contain the same number of words. In a situation where the images were of different heights, or the captions varied in length, some of the floated elements might be different heights. Instead of a neatly aligned set of images, you might have a row of various-height divs that would not neatly align.

One way to resolve this problem is to give the #thumb li rule enough height to accommodate the tallest of the elements. In example 13, I’ve added a few words to one of the captions and changed the height rule to height: 11em.

View Example 13

More about Containing Floats

Example 3 showed you a floated image not completely enclosed within its container. There are several ways to make sure that a container completely encloses any floated elements. Examples 7-10 used the clear: bothproperty on the footer to force the container to stretch far enough to contain the floated element. This works in examples 7-10 because the footer is within the same container element as the floated content div, but sometimes you need to fully contain a floated element that doesn’t meet that criteria.

Three additional methods for containing floats are summarized in example 14.

View Example 14

The first method is to add a non-semantic element such as <div class="clear"></div> after the floated element and inside the container. This class uses the rule:

.clear {
  clear: both;
}

The drawback to this is, of course, the small bit of non-semantic HTML that gets tossed into your document.

A second method of containing floats uses the overflow property. The containing div is assigned an overflow: auto rule, forcing it to expand to contain its floated child elements. Here’s an example:

#container {
  overflow: auto;
}

This works in most modern browsers. Older Mac IE browsers may show a horizontal scroll bar, which is the only drawback to this method. For versions of IE older than IE7 which have a problem with expanding boxes (see below), simply adding a hasLayout trigger to the #container rule achieves the same effect. I used #container {zoom: 1;} in these examples. It does no harm in browsers such as Firefox that don’t understand zoom, and makes IE6 and below behave.

The third method shown in Example 14 uses overflow: hidden. It works almost identically to the overflow: auto method; you won’t get any scroll bars, but some content, such as images, might be clipped.

There’s another method you may run into if you research floats: the easy clearing method, which uses the :after pseudo-class. This method requires a number of hacks to make it work in various browsers. Since the overflow method works well without hacks, I see no reason to resort to a method that requires hacks.

Using float: Caveats and bugs

Older versions of Internet Explorer (6 and below) may hit you with the double-floated margin bug. If an element has a margin on the same side as the direction in which it is floated, IE will double the margin on that side. This one is easily solved with a display: inline rule, as illustrated above.

Another IE-specific problem is the way it treats floats (or indeed any content) that are too large for their containers. If an element becomes too wide (or too tall) for the width and/or height assigned to its container, IE will expand the box to display it all. This may cause adjacent floated elements to drop because there is no longer room for them to wrap as intended. There are several ways to handle this, the easiest of which is overflow: hidden, although that may mean that some content is hidden from view in certain situations. See Resources for a lengthy description of this IE bug and the other choices for workarounds.

Understanding the basic presentation behavior of float discussed here will help you apply the float property in many situations. In addition, the resources below will take you into greater depth on the topic. Go forth and float.

Resources