Practical advice for building websites with web standards
The common approach to laying out a page is through the use of float. A container floated left becomes a left-hand sidebar. And even within components of a page, the float is used to create columnar layouts.
One of the side-effects of using floats for layout is that the element being floated is drawn out of the flow of the content, and the content flows around the floated container. Even though this is the idea behind floats, it’s not entirely ideal for layout.
One too-long floated element, and other components further down end up being flowed around the floated element until the floated-element has been passed, and then the full width of the parent element is available.
This means that components later on in the page typically need some styling to the effect of don’t start appearing until after the floated element has been passed
. Typically, this is done with a clear
CSS property.
Leaving the clearing up of previous floats to the preceding elements isn’t a wise move. It forces the content container to take into consideration the layout it’s placed in. And that introduces assumptions and conflicts into layouts. A content container that’s clearing and previous sibling floats cannot then appear next to a previous siblinb container. So placing two content containers side-by-side is impossible.
A technique that’s prevalent on the web today is the use of an empty div used for the purposes of clearing previous floats. That way the following containers of content don’t have to take into account floated elements in the flow before them. The structure of this technique looks something like this:
<div class="module">
... internal elements, including a floated
elements that may extend longer than the
non-floated content
</div>
<div class="clearfix"></div>
<div class="module">
... Next content containter, thanks to the
previous div.clearfix doesn't need to
worry about whether a floated element will
interfere with it's own layout...
</div>
The .clearfix is normally styled with clear: left
, or clear: both
if the layout may contain elements floated rightwards too.
This makes sense in some way. The next element doesn’t need to deal with extended floating elements, and can assume that it’s been handled.
There are two main drawbacks to this markup-based approach:
And yet, neither sacrifice is necessary. The content container should clean up after itself, and take responsibility for it’s child elements.
Simply, the content containers should always clear any contained floats. We’ve previously discussed methods of self-clearing floats. Applying these techniques we can refactor the above code and removing the extraneous empty div, whose purpose is now properly handled by the content container:
<div class="module">
... the div needs to take responsibility
for it's child content...
</div>
<div class="module">
... Next content containter isn't
hindered by the previous content ...
</div>
And adding in the style rules to self-clear any contained floats:
.module {
overflow: hidden;
}
Note: overflow: hidden
is a stable way of clearing floats, but it does have a drawback of not allowing child content to overflow outside the container’s edges. For the majority of layout scenarios, this is a good thing. In the very few cases where this feature is not desirable, then use an alternative self-clearing method, like the content :after approach, plus an IE-tailored style to force hasLayout.
Content containers that clean up after their child elements reduce the maintenance headache. The order of content on the page can be more flexible. And two blocks of content can be placed side-by-side, with space permitting.
Essentially, self-clearing wrappers become a solid foundation, and so allows more intricate styling by isolating the effects of floated elements just to that atomic unit of content.