The Mystery Of The CSS Float Property
float
property, table-less layouts would be, at worst, impossible, and, at best, unmaintainable. Floats will continue to be prominent in CSS layouts, even as CSS3 begins to gain prominence.Years ago, when developers first started to make the transition to HTML layouts without tables, one CSS property that suddenly took on a very important role was the float
property. The reason that the float
property became so common was that, by default, block-level elements will not line up beside one another in a column-based format. Since columns are necessary in virtually every CSS layout, this property started to get used — and even overused — prolifically.
What Is A CSS Float Property?
The CSS float
property allows a developer to incorporate table-like columns in an HTML layout without the use of tables.
If it were not for the CSS float
property, CSS layouts would not be possible except using absolute and relative positioning — which would be messy and would make the layout unmaintainable.
In this article, we’ll discuss exactly what the float
property is and how it affects elements in particular contexts. We’ll also take a look at some of the differences that can occur in connection with this property in the most commonly-used browsers. Finally, we’ll showcase a few practical uses for the CSS float
property. This should provide a well-rounded and thorough discussion of this property and its impact on CSS development.
Definition And Syntax
The purpose of the CSS float
property is, generally speaking, to push a block-level element to the left or right, taking it out of the flow in relation to other block elements. This allows naturally-flowing content to wrap around the floated element. This concept is similar to what you see every day in print literature, where photos and other graphic elements are aligned to one side while other content (usually text) flows naturally around the left- or right-aligned element.
The photo above shows the "Readers' sites" section of late .net magazine, which displayd 3 readers' photos each aligned left in their respective columns with text wrapping around the aligned images. That is the basic idea behind the float
property in CSS layouts, and demonstrates one of the ways it has been used in table-less design.
The effectiveness of using floats in multi-columned layouts was explained by Douglas Bowman in 2004 in his classic presentation No More Tables:
Bowman explained the principles behind table-less design, using Microsoft’s old site as a case study. Floats were used prominently in his mock overhaul of the Microsoft layout.
Syntax
The float
CSS property can accept one of 4 values: left
, right
, none
, and inherit
. It is declared as shown in the code below.
#sidebar {
float: left;
}
The most commonly-used values are left
and right
. A value of none
is the default, or initial float
value for any element in an HTML page. The value inherit
, which can be applied to nearly any CSS property, does not work in Internet Explorer versions up to and including 7.
The float
property does not require the application of any other property on a CSS element for float
to function correctly, however, float
will work more effectively under specific circumstances.
Generally, a floated element should have an explicitly set width (unless it is a replaced element, like an image). This ensures that the float behaves as expected and helps to avoid issues in certain browsers.
#sidebar {
float: left;
width: 350px;
}
Specifics on Floated Elements
Following is a list of exact behaviours of floated elements according to CSS2 Specifications:
- A left-floated box will shift to the left until its leftmost margin edge (or border edge if margins are absent) touches either the edge of the containing block, or the edge of another floated box
- If the size of the floated box exceeds the available horizontal space, the floated box will be shifted down
- Non-positioned, non-floated, block-level elements act as if the floated element is not there, since the floated element is out of flow in relation to other block elements
- Margins of floated boxes do not collapse with margins of adjacent boxes
- The root element (``) cannot be floated
- An inline element that is floated is converted to a block-level element
Float In Practice
One of the most common uses for the float
property is to float an image with text wrapping it. Here is an example:
The CSS applied to the image in the box above is as follows:
img {
float: left;
margin: 0 15px 5px 0;
border: solid 1px #bbb;
}
The only property required to make this effect work is the float
property. The other properties (margin and border) are there for aesthetic reasons. The other elements inside the box (the `
` tags with text inside them) do not need any styles applied to them.
As mentioned earlier, floated elements are taken out of flow in relation to other block elements, and so other block elements remain in flow, acting as if the floated element is not even there. This is demonstrated visually below:
In the above example, the `
` element is a block-level element, so it ignores the floated element, spanning the width of the container (minus padding). All non-floated, block-level elements will behave in like manner.
The text in the paragraph is inline, so it flows around the floated element. The floated box is also given margin settings to offset it from the paragraph, making it visually clear that the paragraph element is ignoring the floated box.
Clearing Floats
Layout issues with floats are commonly fixed using the CSS clear
property, which lets you "clear" floated elements from the left or right side, or both sides, of an element.
Let’s take a look at an example that commonly occurs — a footer wrapping to the right side of a 2-column layout:
If you view this page in IE6 or IE7, you won’t see any problems. The left and right columns are in place, and the footer is nicely tucked underneath. But in Firefox, Opera, Safari, and Chrome, you’ll see the footer jump up beside the left column. This is caused by the float applied to the columns. This is the correct behaviour, even though it is a more problematic one. To resolve this issue, we use the aforementioned clear
property, applied to the footer:
#footer {
clear: both;
}
The result is shown below:
The clear
property will clear only floated elements, so applying clear: both
to both columns would not cause the footer to drop down, because the footer is not a floated element.
So use clear
on non-floated elements, and even occasionally on floated elements, to force page elements to occupy their intended space.
Fixing The Collapsed Parent
One of the most common symptoms of float-heavy layouts is the "collapsing parent". This is demonstrated in the example below:
Notice that the bottom of the floated image appears outside its parent. The parent does not fully expand to hold the floated image. This is caused by what we discussed earlier: the floated element is out of the flow in relation to other block elements, so all block elements will render as if the floated element is not even there. This is not a CSS bug; it’s in line with CSS specifications. All browsers render the same in this example. It should be pointed out that, in this example, adding a width to the container prevents the issue from occurring in IE, so this would normally be something you would have to resolve in Firefox, Opera, Safari, or Chrome.
Solution 1: Float the container
The easiest way to fix this problem is to float the containing parent element:
Now the container expands to fit all the child elements. But unfortunately this fix will only work in a limited number of circumstances, since floating the parent may have undesirable effects on your layout.
Solution 2: Adding Extra Markup
This is an outdated method, but is an easy option. Simply add an extra element at the bottom of the container and "clear" it. Here’s how the HTML would look after this method is implemented:
<div id="container">
<img src="https://archive.smashing.media/assets/344dbf88-fdf9-42bb-adb4-46f01eedd629/faad51dc-f367-4252-8bf4-2160b5b9ff01/lifesaver.jpg" width="200" height="222" alt="" />
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper.</p>
<div class="clearfix"></div>
</div>
And the resulting CSS applied to the new element:
.clearfix {
clear: both;
}
You could also do this by means of a `
` tag with an inline style. In any case, you will have the desired result: the parent container will expand to enclose all of its children. But this method is not recommended since it adds nonsemantic code to your markup.
Solution 3: The :after
Pseudo-Element
The :after
pseudo-element adds an element to the rendered HTML page. This method has been used quite extensively to resolve float-clearing issues. Here is how the CSS looks:
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
The CSS class "clearfix" is applied to any container that has floating children and does not expand to enclose them.
But this method does not work in Internet Explorer up to version 7, so an IE-only style needs to be set with one of the following rules:
.clearfix {
display: inline-block;
}
.clearfix {
zoom: 1;
}
Depending on the type of issue you’re dealing with, one of the above two solutions will resolve the issue in Internet Explorer. It should be noted that the zoom
property is a non-standard Microsoft proprietary property, and will cause your CSS to become invalid.
So, because the :after
pseudo-element solution does not work in IE6/7, is a little bit bloated code-wise, and requires additional invalid IE-only styles, this solution is not the best method, but is probably the best we’ve considered so far.
Solution 4: The Overflow Property
By far the best, and easiest solution to resolve the collapsing parent issue is to add overflow: hidden
or overflow: auto
to the parent element. It’s clean, easy to maintain, works in almost all browsers, and does not add extra markup.
You’ll notice I said "almost" all browsers. This is because it does not work in IE6. But, in many cases, the parent container will have a set width, which fixes the issue in IE6. If the parent container does not have a width, you can add an IE6-only style with the following code:
// This fix is for IE6 only
.clearfix {
height: 1%;
overflow: visible;
}
In IE6, the height
property is incorrectly treated as min-height
, so this forces the container to enclose its children. The overflow
property is then set back to "visible", to ensure the content is not hidden or scrolled.
The only drawback to using the overflow
method (in any browser) is the possibility that the containing element will have scrollbars or hide content. If there are any elements with negative margins or absolute positioning inside the parent, they will be obscured if they go beyond the parent’s borders, so this method should be used carefully. It should also be noted that if the containing element has to have a specified height
, or min-height
, then you would definitely not be able to use the overflow
method.
So, there really is no simple, cross-browser solution to the collapsing parent issue. But almost any float clearing issue can be resolved with one of the above methods.
Float-Related Bugs In Internet Explorer
Over the years, there have been numerous articles published online that discuss common bugs in connection with floats in CSS layouts. All of these, not surprisingly, deal with problems specific to Internet Explorer. Below, you’ll find a list of links to a number of articles that discuss float-related issues in-depth:
- The Internet Explorer Guillotine Bug
- The IE5/6 Doubled Float-Margin Bug
- IE7 Bottom Margin Bug
- The IE Escaping Floats Bug
- The IE6 Peekaboo Bug
- The IE6 "Ghost Text" Bug
- The IE6 Expanding Box Problem
- The IE6 3-pixel Gap
Changing the Float Property with JavaScript
To change a CSS value in JavaScript, you would access the style
object, converting the intended CSS property to "camel case". For example, the CSS property "margin-left" becomes marginLeft
; the property background-color
becomes backgroundColor
, and so on. But with the float
property, it’s different, because float
is already a reserved word in JavaScript. So, the following would be incorrect:
myDiv.style.float = "left";
Instead, you would use one of the following:
// For Internet Explorer
myDiv.style.styleFloat = "left";
// For all other browsers
myDiv.style.cssFloat = "left";
Practical Uses For Float
Floats can be used to resolve a number of design challenges in CSS layouts. Some examples are discussed here.
2-Column, Fixed-Width Layout
Roger Johansson of 456 Berea Street outlines an 8-step tutorial to create a simple, cross-browser, 2-column, horizontally centered layout. The float
property is integral to the chemistry of this layout.
"The layout consists of a header, a horizontal navigation bar, a main content column, a sidebar, and a footer. It is also horizontally centered in the browser window. A pretty basic layout, and not at all difficult to create with CSS once you know how to deal with the inevitable Internet Explorer bugs."
3-Column, Equal-Height Layout
Petr Stanicek of pixy.cz demonstrates a cross-browser 3-column layout, again using float
:
"No tables, no absolute positioning (no positioning at all), no hacks(!), same height of all columns. The left and right columns have fixed width (150px), the middle one is elastic."
Floated Image With Caption
Similar to what we discussed earlier under "Float in Practice", Max Design describes how to float an image with a caption, allowing text to wrap around it naturally.
Horizontal Navigation With Unordered Lists
The float
property is a key ingredient in coding sprite-based horizontal navigation bars. Chris Spooner of Line25 describes how to create a Menu of Awesomeness, in which the `
To demonstrate the importance of the float
property in this example, here is a screen shot of the same image after using firebug to remove the float: left
:
Grid-Based Photo Galleries
A simple use for the float
property is to left-float a series of photos contained in an unordered list, which gets the same result as what you would see in a table-based layout.
Foremost Canada’s product page (above) displays their products in grid-based format, next to a left-column sidebar. The photos are displayed in an unordered list with the float property for all `
float: left
. This works better than a table-based grid, because the number of photos in the gallery can change and the layout would not be affected.Paragon Furniture’s futons page (above) is another example of a product page using an unordered list with floated list items.
iStockphoto’s search results page (above) is a similarly-structured grid of photos, but this time the photos are contained in left-floated `
Aligning an <input> Field with a Button
Default styling on form elements across different browsers can be a pain to deal with. Often times, in a single-field form like a search form, it is necessary to place the `` element next to the submit button. Here is a simple search form, with an image used for the submit button:
In every browser, the result is the same: The button appears slightly higher than the input field. Changing margins and padding does nothing. The simple way to fix this is to float the input field left, and add a small right margin. Here is the result:
Conclusion
As was mentioned at the outset, without the CSS float
property, table-less layouts would be, at worst, impossible, and, at best, unmaintainable. Floats will continue to be prominent in CSS layouts, even as CSS3 begins to gain prominence — even though there have been a few discussions about layouts without the use of floats.
Hopefully this discussion has simplified some of the mysteries related to floats, and provided some practical solutions to a number of issues faced by CSS developers today.
Further Reading
- Sitepoint CSS Reference: Float
- All About Floats on CSS-Tricks
- Simple Clearing of Floats
- Visual Formatting Model: Floats
- Floating and Clearing