clock

Stop Floating Along, Start Flexing

I was first introduced to the Flexbox spec at An Event Apart DC 2012. It was one of the most obvious improvements to CSS and our battles with floats, yet - not many fully understood the scope of what they were hearing.

As front-end developers, we've been doing the same float business for so long that it has become second nature to us. Even to the point where we could be sitting face to face with one of the biggest layout improvements that has ever come to CSS and not really comprehend or understand the real benefit. At one point Ethan Marcotte stopped speaking, laughed and exclaimed "This is really huge, people! You should be very excited!".

One main breakthrough with Flexbox is DOM independence. Floats still rely on the order in which DOM elements are laid out in your code. For example, in a three column layout you would essentially be (somewhat) restricted to the order of the columns in the DOM. Sure, you could do some nasty float hacks to get the first element to appear last and vice versa, but you'll very likely end up shooting yourself in the foot as you continue developing. We've all been there.

Flexbox is much different. You can specify a direct order to all children of Flexbox no matter where they fall in the DOM. This makes for more refined control without messing with CSS hacks and float clears. It's all handled for you and not only does it control the direction of elements horizontally, it can also control how elements are stacked vertically without any change to your HTML.

Note: Updating the order of elements using flexbox gives us a lot of visual control, but it's also important to keep accessibility in mind when using this feature. In many cases, changing the visual order or elements can lead to reducing the accessibility of your project. With great power comes great responsibility!

Examples

Of course, the best way to illustrate the difference is with code. Let's start with our base HTML like so:

<article id="content">
    <div id="one" class="column">
        <h1>Div One</h1>
        <p>Content</p>
    </div>
    <div id="two" class="column">
        <h1>Div Two</h1>
        <p>Content</p>
    </div>
    <div id="three" class="column">
        <h1>Div Three</h1>
        <p>Content</p>
    </div>
</article>

Now, let's use css to float our list items side by side, as we are used to:

#content {overflow:hidden;} /* You could use alternatively use a clear. */
#content .column {float:left;}

Now, let's take a look at that same example using Flexbox:

#content {display:-webkit-flex; display:flex; flex-flow:row wrap;}
#one {width:23.3%; padding:5%; background:#ccc; -webkit-order:3; order:3;}
#two {width:23.3%; padding:5%; background:#fff; -webkit-order:1; order:1;}
#three {width:23.3%; padding:5%; background:#eee; -webkit-order:2; order:2;}

Okay... So, our code has changed a little and we've negated our need for the additional class, but you're not impressed? Let's imagine that we would like to re-order our floated elements inside of a media query for example.

There are a couple ways of making this change. We could spend far too much time tinkering with floats, clears, positioning and CSS hacks to get our elements reordered correctly or we could just buckle and do the right thing and jump back into our HTML and reorder the elements so they are rendered in the correct order. Personally, I'd vote for the latter. It's cleaner and we don't have to worry about some nasty hack coming back to bite us in the ass. The good news is that Flexbox gives us another option. We can leverage additional attributes in the Flexbox spec to re-order those elements entirely in our CSS without changing a single line in our HTML.

#content {display:-webkit-flex; display:flex; flex-flow:row wrap;}
#one {width:23.3%; padding:5%; background:#ccc; -webkit-order:3; order:3;}
#two {width:23.3%; padding:5%; background:#fff; -webkit-order:1; order:1;}
#three {width:23.3%; padding:5%; background:#eee; -webkit-order:2; order:2;} 

Now, isn't that much easier? With flexbox we now have visual layout independence from our HTML both horizontally and vertically. In our case, we're only taking advantage of a horizontal flex, but you can imagine the level of control you can get with more complicated scenarios. It's really quite impressive.

Conclusion

As of writing this, Flexbox is considered stable and is a W3C Candidate Recommendation. Even with the lack of IE support (IE9 and below), it's a valid investment to understand how it works and how to use it in preparation of its eventual implementation and browser support.

There are some clear criticisms and doubts with Flexbox including some performance concerns. However, In the end I think it all depends on how many folks can put it to good use. If the majority of developers find it beneficial to their design process then the performance enhancements will follow behind and hopefully everyone's concerns will be resolved.

Demo