Three Practical Uses for Flexbox

Warning This article was written over six months ago, and may contain outdated information.

The Flex­i­ble Box Lay­out mod­ule (com­mon­ly referred to as Flexbox, for con­ve­nience) is imple­ment­ed in Fire­fox, Chrome, Safari, and IE10. I wrote an arti­cle explain­ing Flexbox in detail in .net mag­a­zine last year, but thought it worth fol­low­ing up with a short, prac­ti­cal guide on a few things it’s use­ful for.

I actu­al­ly don’t think it’s per­fect­ly suit­ed for com­plex page lay­outs, but it does some sim­ple things very well, so that’s what I’ll con­cen­trate on. There are three use cas­es in this arti­cle, none of which are impos­si­ble using CSS2.1, but all of which are made eas­i­er with Flexbox.

You can see all of the exam­ples in action on this page: 

Demo: Three Prac­ti­cal Uses for Flexbox

Equally-distributed Navigation Items

For the first exam­ple I’m going to make a hor­i­zon­tal tabbed nav­i­ga­tion, where all of the tabs have equal widths and spac­ing. In my exam­ple I have four tabs inside a par­ent which is 600px wide, each tab has a 1px bor­der, and between each of the tabs I have a 4px gap. I can set the tab widths by using absolute num­bers or per­cent­ages* but both of these mean mak­ing cal­cu­la­tions, and hav­ing to recal­cu­late when new items are added — not prac­ti­cal if you cre­ate a web­site for a client with no knowl­edge of CSS.

Using Flexbox makes this much eas­i­er; you just need to give the list par­ent a display val­ue of flex, and each item a flex val­ue of 1. NB: You will have to use pre­fixed prop­er­ties for Chrome and Safari (-webkit-) and IE10 (-ms-); inspect the code of the demo page for details.

ul.nav { display: flex; }
.nav li { flex: 1; }

What this does is dis­trib­ute all of the li ele­ments equal­ly into the par­ent, after mar­gins have been account­ed for; no cal­cu­la­tions are required, and no mod­i­fi­ca­tion of the CSS need­ed if an extra nav item’s added.

Update: As point­ed out in the com­ments, if you have very var­ied text in the list items this actu­al­ly does­n’t work the way you think it should (espe­cial­ly in Fire­fox), as the widths of the tab will vary to fit the con­tent. To work around this in WebKit browsers you just need to add a width val­ue oth­er than auto; even 0 is accept­able. In Fire­fox you need to add a greater width val­ue (in my exam­ple I’ve used 150px which, as there are four chil­dren, is 25% of the par­ent) just to get the lay­out work­ing in the first place, and there is no way to stop the tabs from resizing.

Vertical Centring

Hor­i­zon­tal cen­tring is eas­i­ly achieved by using an auto val­ue for margin-left and margin-right, but ver­ti­cal cen­tring is not so easy; there are a hand­ful of dif­fer­ent meth­ods, but they involve either extra markup, or a fixed height on the cen­tred ele­ment, or both. Flexbox does away with those drawbacks.

In this exam­ple I’m going to cen­tre an ele­ment hor­i­zon­tal­ly and ver­ti­cal­ly inside it’s par­ent, using these rules:

.parent {
  align-items: center;
  display: flex;
  justify-content: center;
}

The align-items and justify-content prop­er­ties con­trol the dis­tri­b­u­tion of unused space on the ver­ti­cal and hor­i­zon­tal axes (respec­tive­ly), so giv­ing them a val­ue of center means all space will be dis­trib­uted equal­ly on all sides, posi­tion­ing its child in the dead centre.

Start and End Alignment

In my third exam­ple I’m going to use a fair­ly com­mon design pat­tern, which is two ele­ments posi­tioned at oppo­site ends of their par­ent, on the same axis. This is quite often seen in head­ers and foot­ers, and the way to do this cur­rent­ly is using either absolute posi­tion­ing or floats; both involve set­ting dimen­sions, so aren’t very flexible.

With Flexbox this can be done with the justify-content prop­er­ty we saw in the pre­vi­ous exam­ple, but with a val­ue of space-between:

.footer {
  display: flex;
  justify-content: space-between;
}

The two p ele­ments in the foot­er are dis­played jus­ti­fied in their par­ent — that is, one at each end of the .foot­er element.

Wrapping Up

So can you use FlexBox on your sites today? I think so, if you take care; you can detect sup­port using Mod­ern­izr, and pro­vide fall­backs for incom­pat­i­ble browsers.

Update, July 2013: This arti­cle was updat­ed to include the cor­rect Flexbox syn­tax; the pre­vi­ous ver­sion con­tained out­dat­ed code exam­ples and text, so has been edit­ed to clear that up — although some ref­er­ences in the text may no longer apply in mod­ern browsers.

5 comments on
“Three Practical Uses for Flexbox”

  1. What you call Flexbox, which seems to be the CSS stan­dard they’re try­ing to imple­ment, I more often see as “Flex­i­ble Box Mod­el.” And then there is a pop­u­lar jQuery plug-in that is called FlexBox. Could be con­fus­ing to readers.

    PixelTunnelVision [August 31st, 2011, 16:12]

  2. Total­ly agree that the flex­i­ble box lay­out mod­el is not great for full-page lay­outs but good for indi­vid­ual areas of a page. It’s great to see ideas for prac­ti­cal use–thanks!

    How­ev­er, your first exam­ple of equal­ly sized nav­i­ga­tion tabs won’t work. Set­ting the box-flex val­ue to 1 on all the tabs will not make them all the same size–try putting a real­ly long word in one and a real­ly short word in anoth­er and you’ll see what I mean. It’s hard to explain briefly; I explain in ful­ly on pages 248–250 in my book Stun­ning CSS3.

    This is a com­mon mis­con­cep­tion with the box-flex prop­er­ty, one that I think is most­ly to blame on the spec–it should be clear­er, and the def­i­n­i­tion is not intuitive.

  3. Hi Zoe, thanks for your comment.

    I see what you mean; this is cer­tain­ly the case in Fire­fox. In WebKit you can give any width val­ue oth­er than auto (even 0 is okay) in order to make the widths equalise. I’ll test it in IE10 and see what the result is there, and I’ll update my post lat­er to make sure this is clear.

  4. I made my recent relaunch with flex box lay­out — as a full page lay­out. This was not that bad at all. I would not say flex box is not good for full page layout.
    Espe­cial­ly I had to con­sid­er acces­si­bil­i­ty issues — it was a lit­tle bit tricky to get flex box right for page & text zoom. And in com­bi­na­tion with media queries it was quite a per­fect solution.

    And if flex box attribute box-lines is ful­ly sup­port­ed you can get a real flex­i­ble box mod­el running.

  5. I would­n’t want to cre­ate call­backs for a mod­ern brows­er like IE9, since it’s the newest brows­er that runs on Vista and the default brows­er on Win­dows 7. Also it’s not par­tic­u­lar­ly old.

    Because of this, I tend to deem Flexbox unus­able today and in the very near future. Espe­cial­ly because with­out it *and* javascript the page would explode, probably.