No compatibility problems. Incredible, isn't it?
A common problem with float-based layouts is that the floats' container doesn't want to stretch up to accomodate the floats. If you want to add, say, a border around all floats (ie. a border around the container) you'll have to command the browsers somehow to stretch up the container all the way.
Let's try it. This is the CSS we'll use throughout the page:
div.container { border: 1px solid #000000; } div.left { width: 45%; float: left; } div.right { width: 45%; float: right; }
Now this happens:
The left column.
The left column.
The left column.
The left column.
The right column.
The right column.
The right column.
We want the black border to go around both our floating columns. That doesn't happen, though. The container div itself has no height, since it only contains floating elements. Therefore the border stubbornly stays at the top of the floating columns.
The old solution to this problem required you to add an extra element with clear: both
to the container. Once it was in place the container contained a non-floating element, which means it stretches
itself up to accomodate it:
The left column.
The left column.
The left column.
The left column.
The right column.
The right column.
The right column.
clear: both
This can be done either by adding the extra element in the HTML source code (as the example above does)
or by using the :after
pseudo-class to generate it. Since
Explorer (Win and Mac) doesn't support :after
this second solution was mainly of theoretical
interest.
In any case, adding an HTML element for presentation's sake is something we've learned to avoid. Unfortunately the problem could not be solved in any other way, until now.
It was Alex Walker who first posted a new, simpler solution, though he gives the credits for actually inventing it to Paul O'Brien. In any case, the solution seems to be:
div.container { border: 1px solid #000000; overflow: auto; width: 100% }
The width
is necessary to trigger "hasLayout" in Explorer Windows (except for 7). This works:
The left column.
The left column.
The left column.
The left column.
The right column.
The right column.
The right column.
Now the border neatly fits around the floated elements.
A few points merit extra attention:
overflow
values: auto, hidden and scroll. Of
course, using the last value will show scrollbars, regardless of whether they're needed or not.width
or height
for the container
div.The use of a width
or height
declaration is required to make the effect work
in Explorer Windows and Opera. If you don't include it Explorer Windows continues to show the border at
the top of the columns, as if there were no overflow
. Opera completely hides the content of
the container.
A width: 100%
is a neat starting point, although more complicated layouts may require other
values.
hidden
If Explorer Mac is still important to you, use overflow: hidden
. This browser always shows
scrollbars when you use overflow: auto
; and I'm not sure why.
As Dave Shea
noted, this solution might cause unwanted scrollbars if the content escapes from the container
box. Personally I wonder if this will be a serious problem. overflow: hidden
makes sure that
no scrollbars will ever be visible. Of course some content might be hidden instead, but if we make very
sure that
this problem will never creep up.
On the other hand, never say never. In pure tests like the ones above the effect works fine. In real-world sites, where there's plenty more CSS to confuse browsers, something will eventually go wrong somewhere. Until we reach that point, though, this technique will do nicely.
For completeness' sake, here's the code you need:
div.container { border: 1px solid #000000; overflow: hidden; width: 100%; } div.left { width: 45%; float: left; } div.right { width: 45%; float: right; }