Farewell Floats: The Future of CSS Layout

Floats are one of the most basic tools for structuring a web page using CSS. They’re both one of the very first things that we learn about and one of the last things that we truly master.

Today’s article looks at some of the reasons that floats are pretty lame and takes a look at a number of alternative layout systems, some of which are still under development but may one day represent the standard for CSS-based layout.

A Tale of Tables

Once upon a time, web designers used HTML tables to accomplish complex page layouts. Though it was a messy, non-semantic process, it attempted to make the best of the available technology to create better designs.

For newbies, when I say “non-semantic,” I mean that table-based layout is a bastardization of the table element. It’s meant to hold actual tables of information within a page, not to serve as the structure for the page itself.

Floats: The New Tables?

Today, we scoff at this practice. What a silly way to lay out a website! CSS has come to our rescue and provided us with several tools for creating much more semantic layouts that can easily achieve anything that was created with a table.

Today one of the primary ways that we have replaced our table-dependent ways is the use of floats for layout. By default, sequential HTML elements will appear vertically stacked. Floats serve as a way for us to line elements up horizontally. Float a list of li elements to the left and you’ve got yourself a nice little horizontal navigation menu.

Though many of us have simply grown accustomed to using them, floats are far from ideal. They’re awkward, buggy and difficult to learn. If you think back to when you first began CSS-based layout, the thing that had you scratching your head and troubleshooting for hours was probably a float gone wrong.

The Clearfix Band-Aid

The bane of float-based layouts (aside from IE6 margin nightmares) is of course the fact that they simply don’t play well with their container elements. In order to get the parent element to appear as if it contains floated elements, we typically insert a cleared element last in the container using “clear:both”.

Is creating an empty container to hack a broken layout a good practice? Probably not. Does it work? You bet.

A Better Clearfix

Forward thinkers have decided that this business of adding additional HTML markup is no good. The current favorite way to clear a float is to instead insert the new element using the CSS “:after” pseudo class.

.clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } 1 2 3 4 5 6 7 . clearfix : after { content : "." ; display : block ; height : 0 ; clear : both ; visibility : hidden ; }

Once again, this is acceptable because of how accustomed we are to messing with floats to bend them to our will. However, try taking a step back and really looking at what’s going on here. This is a mess! We’re using CSS to insert an invisible element into the HTML so that our layout problems magically disappear as we shiver at the thought of using table-based layouts because they aren’t semantic.

I’m not defending table-based layout, it’s dead and needs to stay that way, but I can’t help but wonder if future web designers will laugh at our use of floats the way that we now laugh at the thought of a web page built on a table.

The Future

You have to admit, if you really think about it, floats are a pretty screwed up and complicated way to handle page layout. I don’t see floats going completely away any time soon, they’ll likely still be useful even if we all do accept a new layout process.

However, there are several interesting layout tools on the horizon that could very well replace floats as a primary way that to structure web pages. Let’s take a look at some of these ideas and constructs and see if we can get a glimpse into what the future of CSS layout will be like.

Inline-Block

Before we dive into futuristic experimental layout techniques, it’s worthwhile to discuss inline-block as an interesting alternative to float-based layouts. Consider the snippet below:

ul li { display: inline-block; width: 100px; min-height: 100px; vertical-align: top; /*helps with variable length content*/ } 1 2 3 4 5 6 ul li { display : inline - block ; width : 100px ; min - height : 100px ; vertical - align : top ; /*helps with variable length content*/ }

This will actually cause our list items to appear inline while retaining their block attributes, which is completely amazing really! We get the best of both worlds.

Downfalls of Inline-Block

Andrew Tetlaw from Sitepoint recently published a fantastic article that highly praises using inline-block over floats. He correctly points out that this method works effectively on all modern browsers, including IE8 and above, which is about the same as you can expect from the pseudo-class-driven clearfix from above.

Unfortunately, as Robert Nyman points out in a similar article, this method isn’t without its problems.

In addition to the IE troubles (he has a clever hack to get support in IE7), Nyman shows using inline-block causes your layout to be somewhat whitespace dependent when it comes to your HTML. The example he uses is the following unordered list:

<ul id="display-inline-block-example"> <li>Item one</li> <li>Item two</li> <li>Item three</li> </ul> 1 2 3 4 5 < ul id = "display-inline-block-example" > < li > Item one < / li > < li > Item two < / li > < li > Item three < / li > < / ul >

Believe it or not, the line returns automatically cause a slight margin to be added to the list items! The only way to fix it is to place them on the same line:

<ul id="display-inline-block-example"> <li>Item one</li><li>Item two</li><li>Item three</li> </ul> 1 2 3 < ul id = "display-inline-block-example" > < li > Item one < / li > < li > Item two < / li > < li > Item three < / li > < / ul >

Admittedly, it’s a fairly easy fix, but if you’re a fan of neatly organized code, this may make you cringe. On the whole, when compared to the trouble that we face using floats, Tetlaw has a point that this may be a better solution that you can actually use now with an acceptable amount of browser support.

Flexbox

One of the new ways that CSS3 is changing layout practices is through the Flexible Box Module, or Flexbox for short. Here’s a quote from the Flexbox w3 abstract.

[Flexbox] provides an additional layout system alongside the ones already in CSS. [CSS21] In this new box model, the children of a box are laid out either horizontally or vertically, and unused space can be assigned to a particular child or distributed among the children by assignment of “flex” to the children that should expand. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions.

Flexbox represents a completely new way to layout websites. You may have heard about this recently but the syntax is changing a bit so make sure you keep an eye on the working spec to stay up to date (I believe “box” will change to “flex” or “flexbox” in most cases). The current working CSS syntax for applying flexbox is as follows:

display: box; display: -webkit-box; display: -moz-box; 1 2 3 display : box ; display : - webkit - box ; display : - moz - box ;

To see how it works, let’s jump right into an example. Basically, once you apply display: box to the parent element, the children can be automatically redistributed based on simple relative sizing.

Imagine we have three paragraph tags (these will serve as columns) inside a parent container with display: box applied and we want the middle column to be twice the width of the other two. Here’s what we do:

#box2 { -webkit-box-flex: 1; -moz-box-flex: 1; box-flex: 1; } 1 2 3 4 5 #box2 { - webkit - box - flex : 1 ; - moz - box - flex : 1 ; box - flex : 1 ; }

With that little bit of code (plus some superfluous visual styling), we can achieve the following result.

Note that the default value is “0” for box-flex. Changing the second box to “2” triggered the command to fill the width while making the second box wider than the other two. Let’s consider a few more examples so you can really get a feel for how it works.

As you can see, Flexbox has dramatic implications to the way we structure websites with CSS. Not only does this have the potential to solve the problems associated with floats, it makes multi-column grid-based layouts infinitely easier!

Dig Deeper

This article is merely meant as an introduction to new layout methods and is not in any way exhaustive. I’ve barely scratched the surface of what what Flexbox can do. For instance, you can accomplish the same thing we did above with vertically stacked elements and completely rearrange the boxes using only CSS.

For more on what can be done with Flexbox, I highly recommend that you play with Flexie, The Flexbox Playground. This will give you hands-on experience with the new layout system and allow you to try each setting to get a feel for the result.

The Template Layout Module

Another proposed idea for CSS layout is the Template Layout Module. Here’s a quote from the official spec.

“The properties in this specification work by associating a layout policy with an element. Rather than letting an element lay out its descendants in their normal order as inline text or as blocks of text (the policies available in CSS level 1), the policy defined in this module, called template-based positioning, gives an element an invisible grid for aligning descendant elements.”

The Template Layout Module uses a quirky but straightforward syntax that makes layout a breeze. The first thing you need to do is create a container with some child elements. For each child element, you assign an arbitrary letter (it doesn’t matter which letter, just make sure they’re unique).

#div1 { position: a; } #div1 { position: b; } #div1 { position: c; } 1 2 3 4 5 6 7 8 9 10 11 #div1 { position : a ; } #div1 { position : b ; } #div1 { position : c ; }

Next, you apply a display value to the parent element using these letters to define your proportions. For example, to create three equal columns, simply type them all in a row:

#container { display: "abc"; } 1 2 3 #container { display : "abc" ; }

This will give you the following result:

If you want to rearrange the boxes, simply rearrange the letters in your CSS. Instead of typing “abc”, try typing “bca”.

To create a new row, create a new set of quotes. You can repeat letters to set a sense of proportion. For instance, here we set the first row to “ab” and the second to “cc”, meaning “c” will be twice the width of “a” or “b”.

Each section (a,b,c) is referred to as a “slot”. To create an empty slot, simply use a period: “a.b.c” will create two empty slots in our row. To target a slot for additional styling, you use the slot pseudo element:

#container::slot(c) {background: gray;} 1 #container::slot(c) {background: gray;}

Dig Deeper

As with the previous example, there’s a lot more that can be done here such as setting heights and widths using precise dimensions or percentages. None of it is ready to use in any browser at the moment but you can install a jQuery plugin to test it out! Check out the plugin’s demo pages for some awesome coded examples of how to create any layout you want using the Template Layout Module.

Back to Tables?

The Andrew Tetlaw Sitepoint article that I mentioned before presents one more interesting option for layout.

.nav > ul { display: table; border-spacing: 0.25em; } 1 2 3 4 . nav > ul { display : table ; border - spacing : 0.25em ; }

Interestingly enough, setting the “display” property to “table” allows us to structure our layout as if they were tables. Right away I know this is going to freak a lot of people out. Reverting back to table-based layout!? Are you nuts? The crazy part is though that this is in fact a completely different practice than literally using a table element. Here you’re simply telling the CSS to position elements similarly to how table cells and rows are positioned.

Personally, I still like the new fancy CSS3 methods that we just covered a lot better and really have a hard time imagining this gaining widespread acceptance, but it’s worth checking out and discussing nonetheless. If you’re interested, be sure to check out Tetlaw’s explanation.

Conclusion

The point of this article was to get you thinking about how floats may not necessarily be the best way to structure websites. Though they’re one of the best solutions that we can currently use in live client projects, they represent a fairly sloppy and broken system that is far from ideal.

There are a number of ways that you can address the downfalls of floats. For now, you could check out “display: inline-block” as one option or even look into “display: table” if you’re particularly brave.

The wizards that make all this technology work recognize that the system is broken and are hard at work solving the problems with layout modules that may prove extremely useful in the future. Expect to hear a lot more on the Flexbox and Template Layout modules in the future. Who knows, one or both of these could be the standard way that future developers create web layouts!

Leave a comment and let us know your thoughts on all this. Do you think floats represent a flawed layout system? Do any of the proposed layout modules seem like a solid fix for these issues?