Flexbox in the Real World

I've been writing about and teaching flexbox for awhile now, and the most common question people ask is, "When will support be good enough for me to use flexbox in a real project?"

I've always thought flexbox has a place in rapid prototyping. But I also think that with a little planning, many of us could be using flexbox in production today.

In this article, we will explore options for when flexbox can be used in production, starting with the best case scenario and working our way down to IE8.

The demo we'll be using is the sign up page for a side project a friend of mine is working on. Pete ran into a few layout problems using Bootstrap's grid system that are easily solved with flexbox, so it's a great example. Here's the layout we'll be creating.

The code for the examples is on Github here.

The four scenarios we will cover are:

Scenario #1: You only need to support bleeding edge browsers.

We're starting with the best case scenario but we'll get to IE8 soon enough.

You can see a live demo of this scenario here and look at the code here.

When I look at the traffic logs for my sites, IE practically doesn't exist. Only about 1% of my traffic is IE10/11. This blog and my product pages are made for web developers like you, so I only need to support the latest browsers that people like us tend to run.

If your traffic looks like this, then you can use the latest flexbox syntax today, right now, with a few caveats:

Follow these rules, and you should be good to go.

Let's write the flexbox layout code for the example.

The top box with the different pricing plans is a flex container, and Pete wants the buttons to be lined up at the bottom. If the outer container is a flex container with align-items set to stretch, (the default), then all of the boxes will have equal height and it's easy to put the buttons at the bottom with an auto margin on the buttons.

First, make the entire section a flex container.


.plans {\n  display: -webkit-flex;\n  display: flex; }\n

This puts them into a row and stretches them vertically.

Then make each of the pricing tiers a flex container. Change the direction to column and align-items to flex-start; otherwise the buttons will stretch to fill the horizontal space.


.plans > div {\n  display: -webkit-flex;\n  display: flex;\n  -webkit-flex-direction: column;\n  flex-direction: column;\n  -webkit-align-items: flex-start;\n  align-items: flex-start; }\n

All that's left is to put the buttons at the bottom of each section. Select each of the buttons and set margin-top: auto.


.plans > div a {\nmargin-top: auto; }\n

I used flexbox in a few other spots on the page in similar ways, but since I'm assuming you know flexbox already, I won't go into more detail. (Dont' know flexbox yet? Go here.)

Scenario #2: You have very little IE traffic.

The live demo for this scenario is here and the code is here.

Even with only a trickle of traffic from older browsers, it's likely you'll still want IE10 and Firefox 25 or older to work.

If you combine the previous versions of flexbox with the latest syntax, you bring IE10 and older versions of Firefox, Safari, and Opera into the fold. (Check out caniuse for more detail on supported browsers.)

It's tedious to write the syntax for every version of flexbox plus all the prefixes, so use Autoprefixer instead. If you're not already using Grunt/Gulp/makefiles/or whatever, this will get you started with Grunt and Autoprefixer.

Don't use auto margins with this approach, since they won't work in every version. Also be sure to test thoroughly in IE10, which has a few bugs. For example, I had to set the width to 100% on the paragraph above the buttons in the code for the demo. Otherwise, the text spilled out of the containers for some reason. (Without auto margins, I had to flex this paragraph to push the buttons to the bottom.)

To give you some sense of the code generated by autoprefixer, here's the code for the pricing packages section.


.plans {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -ms-flexbox;\n  display: flex; }\n  .plans > div {\n    -webkit-box-flex: 1;\n    -webkit-flex: 1 1 33%;\n    -ms-flex: 1 1 33%;\n    flex: 1 1 33%;\n    display: -webkit-box;\n    display: -webkit-flex;\n    display: -ms-flexbox;\n    display: flex;\n    -webkit-box-orient: vertical;\n    -webkit-box-direction: normal;\n    -webkit-flex-direction: column;\n    -ms-flex-direction: column;\n    flex-direction: column;\n    -webkit-box-align: start;\n    -webkit-align-items: flex-start;\n    -ms-flex-align: start;\n    align-items: flex-start; }\n    .plans > div .stretch {\n      width: 100%;\n      -webkit-box-flex: 1;\n      -webkit-flex: 1 0 auto;\n      -ms-flex: 1 0 auto;\n      flex: 1 0 auto; }\n

With Autoprefixer, you get this code automatically, so you only write the latest syntax. An extra bonus is that you get this for all your CSS, and not just for flexbox.

Scenario #3: You have to support IE8, but it doesn't have to look as nice.

The live demo for this scenario is here and the code is here.

Most clients and bosses want their websites to look the same in every supported browser, but a few of us have clients and bosses who buy into progressive enhancement.

In this case, progressive enhancement doesn't necessarily mean IE8 users get a single column of content. You can use an older style layout hand in hand with flexbox. Flexbox will take over when applicable, but browsers that don't support it will ignore the flexbox layout and fall back to the simpler layout.

Zoe Gillenwater did a great presentation on this a few months back. Here's a link to her presentation.

This is the most bulletproof way to use flexbox and support older browsers, but it also means duplicating some of your layout code and figuring out what's "good enough" with a client or boss can sometimes be difficult.

To keep things simple for our example, we'll give up on the buttons being lined up at the bottom in IE8 and IE9. But we still need the pricing section to line up horizontally, so we can use floats.


.plans > div {\n  width: 33%;\n  float: left;\n  flex: 1 1 0;\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start; }\n

(Note: I'm showing only the latest flexbox syntax here, but this code is autoprefixed in the live demo.)

The flex-direction is set to column, and each of the elements in the plan section is a block element. Since they stack in a column already, we don't need to do anything else there.

The sign up box is a flex container, so we'll set the width and the display properties.


.well form .inputs #email {\n  width: 50%;\n  display: inline;\n  flex: 1 0 auto; }\n.well form .inputs .btn {\n  width: 250px;\n  width: 25rem;\n  margin-left: 16px;\n  margin-left: 1rem; }\n

The footer is also a flexbox, so I made it work with a few floats. You should get the idea at this point. Here is what it looks like in IE8.

Scenario #4: You have to support IE8 and 9, and it needs to look exactly the same.

The live demo for this scenario is here and the code is here.

If you find yourself in this category, you may not want to use flexbox at all. You're not completely out of luck, but the options available to you are limited.

There is a flexbox polyfill called flexie.js. It only works with one of the older syntaxes, and not the new syntax. You might be thinking that you could use Autoprefixer and load flexie.js for IE9 and older, but it doesn't work.

There are a few problems. The first problem is that flexie.js looks for unprefixed CSS. But Autoprefixer does not generate unprefixed CSS for the old syntax, probably because it's not used by any browser.

You can get around this problem by patching flexie.js, but you're still not out of the woods. Flexie.js is buggy when you have flexbox rules within media queries because it has a hard-coded version of Selectivizr, which doesn't work with respond.js.

Until it's fixed (if ever), the only solution I can think of is to create an IE8/9 only stylesheet with the old unprefixed flexbox syntax.

Even then, you can't just use flexbox and expect everything to work. You definitely can't use auto margins. You have to keep the layout as simple as possible. I found that I couldn't always get the old flexbox syntax to do exactly the same thing as the new syntax, especially with the polyfill.

But if you aren't using media queries, with a little love, you can get flexbox to work back to IE8.

In the example code, you can find a copy of the patched version of flexie.js I used. I did the quickest thing possible to get it to work, so don't use it in production. If you find yourself needing flexie.js in production, do everyone a favor, put together a real patch, and send it to the author of flexie.js.

Polyfill for the modern syntax

What we really need is a polyfill for the modern syntax. The good news is that Richard Herrera, the guy who wrote flexie.js, is working on it. But right now, it's not even close to being finished.

Learn the new flexbox syntax

The new flexbox syntax hasn't been stable for very long, so not many of us know it yet. If you've been thinking about adding it to your web development arsenal, I've got the perfect thing for you.

I've been working on a free course for flexbox, and the article you just read happens to be the last lesson in the series. So if you liked this and you want to get the rest, clicky-click right here.

Sketching with CSS will teach you how to design in the browser.

Sketching with CSS

Blow away your clients with your fast turnaround time. Bend CSS layouts to your will. Show your clients comps they can actually click on.

Get a free chapter and an 8 day email course on rapid prototyping in the browser.

Share this article with your friends:

Hey there, I'm Sean.

I'm probably a lot like you. I make stuff for the web. I have a CS degree, but the last 11 years of my career have been a more potent teacher.

Sean Fioritto

Recently, I wrote a book on web development called Sketching with CSS. I also run a training company for developers. I'm an author in Smashing Magazine and I've written some cool open source projects.

Today, I'm an entrepreneur. In the not so distant past I did the usual 9-5 thing doing web development for a couple of big companies.

I'd love to meet you on Twitter.

You can also email me: [email protected]