Using Flexbox Now.

,
Looks like this article is pretty old. Some of the information and/or techniques may now be obselete. Just sayin’

As a web designer I’m always excited about using the latest CSS tools, and lately I’ve been giddy about Flexbox. For some time now web designers have been using positioning and/or floats to specify layout, because those were the only tools available to us in CSS1 and CSS2. We’ve grown comfortable with these methods, but they’re really kind of hacks when you think about it.

Now we have Flexbox – a genuine layout tool. No more hacks. With Flexbox, you can divide child elements equally as columns, or as a row of boxes with equal height – a row that reflows onto a new line if the viewport shrinks, and so on. Flexbox elements can have pixel widths, percentages, ems, vws, fixed and flexible widths combined… Oh happy day!

So what’s stopping us?

Chris Coyier’s recent article ‘Using Flexbox: Mixing Old and New for the Best Browser Support’ made me want to dive right in and start using Flexbox today. It seems modern browsers are all cool with Flexbox, so long as you serve each their preferred syntax. Oh, and ordering is paramount too. That aside, we’re good to go right?

Wrong. Chris’ write-up (great though it is) doesn’t offer a solution for Internet Explorer 9 and older. No Flexbox support there, and that’s still a big chunk of users in 2013. Maybe we’ll have to pop Flexbox back on the shelf for a little while longer.

Conditional classes to the rescue

We can actually start creating Flexbox layouts today, and serve the old positioning/float layout methods to older IE via conditional classes. Here’s how it works. Let’s take Chris’ markup as a starting point:

<div class="page-wrap">
	
	<nav class="main-nav" role="navigation">
		Links
	</nav>
	
	<section class="main-content" role="main">
		Main content
	</section>
	
	<aside class="main-sidebar" role="complementary">
		Sidebar
	</aside>

</div>

The keen eyed amongst you will notice I reordered the elements slightly to put the main content back in the middle. Flexbox allows you to use styles to re-order elements visually, regardless of their source order. But there’s no way of achieving this with CSS for older IE I’m afraid, so we’ll need to respect source order for a little while longer. Anyway, onwards.

Let’s add some conditional comments to the top of our document to establish which version of IE we’re dealing with:

<!DOCTYPE html>
<!--[if lt IE 7]><html class="no-js lt-ie10 lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]><html class="no-js lt-ie10 lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]><html class="no-js lt-ie10 lt-ie9"> <![endif]-->
<!--[if IE 9]><html class="no-js lt-ie10"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
	<meta charset="utf-8">	
	<title>Flexbox</title>
	<!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
</head>

No question conditional comments are a hack, but they’re a necessary evil in this and many other instances. Firstly, we’re adding classes to the <html> tag so we can target different versions of Internet Explorer. Since IE10 supports Flexbox, the only versions we’re interested in for this example are .lt-ie10 (less than IE10).

Also, I’m using html5shiv which is a commonly used JavaScript workaround to help older IE cope with the latest HTML5 elements like <section> or <aside>. Without that script our styles for these elements would just be ignored in <IE10.

Now the CSS.

.page-wrap {
	display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
	display: -moz-box;         /* OLD - Firefox 19- (buggy but mostly works) */
	display: -ms-flexbox;      /* TWEENER - IE 10 */
	display: -webkit-flex;     /* NEW - Chrome */
	display: flex;             /* NEW, Spec - Opera 12.1, Firefox 20+ */
 }
.main-content {
	background-color: #eee;
	padding: 2em;
	width: 60%;
}
.main-nav, .main-sidebar {
	-webkit-box-flex: 1;      /* OLD - iOS 6-, Safari 3.1-6 */
	-moz-box-flex: 1;         /* OLD - Firefox 19- */
	width: 20%;               /* For old syntax, otherwise collapses. */
	-webkit-flex: 1;          /* Chrome */
	-ms-flex: 1;              /* IE 10 */
	flex: 1;                  /* NEW, Spec - Opera 12.1, Firefox 20+ */
	padding: 2em;
}
.main-nav {
	background-color: #999;
}
.main-sidebar {
	background-color: #ccc;
}

/* Older MSIE workarounds */
.lt-ie9 article, .lt-ie9 aside, .lt-ie9 nav {
	display: block;
}
.lt-ie10 .main-content {
	float: left;
	padding: 2em 3%;
	width: 54%;
}
.lt-ie10 .main-nav {
	float: left;
	padding: 2em 3%;
	width: 14%;
}
.lt-ie10 .main-sidebar {
	float: left;
	padding: 2em 3%;
	width: 14%;
}

The top portion of these styles is taken from Chris’ article, I’ve just added some background colours to show up the columns better in the browser. The bottom half is where we use our conditional classes, and do our float fallback.

Firstly (for <IE9) we get the <article>, <aside> and <nav> displaying as block-level elements, just as they would in modern browsers. Next, since <IE10 will simply ignore all our earlier Flexbox declarations, we can use conditional classes (.lt-ie10) to target those browsers and use the old float method for layout. Job done.

A quick cross-browser test in BrowserStack came up trumps (apart from a width issue in Firefox which I’m looking into). So if you’re okay about mixing old and new Flexbox syntaxes in your styles (and why wouldn’t you be?), then now might be the time to start using Flexbox on live projects.

Let us help tell your story.

Ready to inject some karma into your project?

Get started