Floats are dead. Long live table layouts.

The CSS float property is the building block of the present web page. For the last decade it’s been unrivalled in laying out content into columns and grids. Except floats exist only for one reason: Shifting a box to the left or right so that content can flow around the outside.

Text flowing around a floating box

You might have done this many times when inserting media into your word processor and not realised that this is how you build web pages. It’s an “ingenious use of the materials available” but stands out as inappropriate when our disposition is to believe in how advanced CSS has become.

Say what?

I don’t want to teach anyone to suck eggs so if you’ve spent your evenings reading CSS specifications it may be wise to skip to the next section.

Floating elements are shifted to the left or right of the current line. Multiple floats can be placed adjacently if there is enough horizontal space.

A block lacking any flow content will collapse

Floating elements no longer flow and therefore do not affect the preceding elements layout, so a parent block lacking any other content will collapse as if empty. Forcing the parent container to wrap around the floats and contain them vertically requires triggering a new block formatting context1 or inserting a pseudo-element with float clearing properties after the contents. Usually overflow: hidden or ::after { clear: both; } respectively.

Triggering a new formatting context will force a block to wrap floats

Both of these methods are ugly, somewhat hard to understand (“Why is this so ugly?”) and may cause further issues when used over-zealously. I think these techniques have been used so much we don’t even blink or take a step back to realise what they are actually doing. A new Intrinsic and Extrinsic sizing module is under discussion with the intention to better describe box sizing, including the addition of key words for containing floats (E.G. min-height: contain-floats;). I hope the module is picked up as a logical progression but it takes us no closer to elegantly defining page layouts.


There are a few layout module specs reaching maturity but none seem unified for creating full page layout (Grid layout aside but it’s still some way off), only parts thereof. I may be short-sighted in seeing the possibilities and timid that any usage of these magical new modules “won’t work on my clients corporate box within the next 5 years” but I don’t see any practical replacements arising in the near future. When grid layout does reach maturity I hope we are not in a position to require a fall-back; there isn’t one.

Is the future really from the past?

In 2002 CSS 2.1 introduced the visual table model. In an effort to wean developers away from misusing tables as a means to format a document new properties were added to assume the same valuable layout characteristics. However the collection of properties have been really underused, partly due to CSS 2.1 not reaching candidate recommendation until 2011 and any hope of capturing developer adoption was thwarted by the usual suspect. Support arrived in Internet Explorer 8 in 2009, too late to effect the clearfixing habit. There are undoubtedly issues too with the (lack of) naming conventions of associated properties and unfamiliar form of the default layout algorithm. Familiar box model dimensions, padding, margins and borders have analogues with some table model specific property names.

Table formatting however can be awesome as it can behave in ways similar to border box sizing or fluxing flexible box layout proposal and combat gritty problems such as columns within elements with no width, vertically even columns and avoid rounding errors in flexible grids. It may be more useful than you might think.

I realise this post is introducing nothing new and all development decisions are bound by context, but with developer support for IE7 starting to come to an end you could find “the visual table model” fits many of your layout needs quite comfortably in the very near future.

  1. The visual formatting specification states that “a new block formatting context must not overlap the margin box of any floats in the same block formatting context as the element itself”. For more human-readable details check out this heroic Stack Overflow answer