Mozilla

The CSS 3 Flexible Box Model

This article about the Flexible Box Layout was written by Jérémie Patonnier, French open Web enthusiast.

The flexible box model

CSS 3 introduces a brand new box model in addition of the traditional box model from CSS 1 and 2. The flexible box model determines the way boxes are distributed inside other boxes and the way they share the available space.

You can see the specification here.

This box model is similar to the one used by XUL (the user interface language used by Firefox). Some others languages use similar box models such as XAML or GladeXML.

Usually the flexible box model is exactly what you need if you want to create fluid layouts which adapt themselves to the size of the browser window or elastic layouts which adapt themselves to the font size.

In this article, all my examples are based on the following HTML code:

<body>
  <div id="box1">1</div>
  <div id="box2">2</div>
  <div id="box3">3</div>
</body>

Distributing boxes: so what?

By default, the traditional CSS box model distributes boxes vertically depending on the HTML flow. With the flexible box model, it’s possible to specify the order explicitly. You can even reverse it. To switch to the flexible box model, set the property display to the value box (or inline-box) on a box which has child boxes.

display: box;

Horizontal or vertical distribution

The box-orient property lets you specify the distribution axis. vertical and horizontal values define how boxes are displayed. Other values (inline-axis and block-axis) have the same effect, but also let you define the baseline alignment itself (basically the boxes are treated like “inline” boxes).

body{
  display: box;
  box-orient: horizontal;
}

Reversed distribution

The property box-direction allows you to set the order in which the boxes appear. By default–when you simply specify the distribution axis–the boxes follow the HTML flow and are distributed from top to bottom if you are using a vertical axis and from left to right if you are using a horizontal axis. By setting box-direction to reverse, you can reverse the boxes’ distribution order. It acts as if you actually reversed the order of the elements in the HTML.

Be careful with this property because it changes the way some other properties work, which can produce some unexpected behavior.

body {
  display: box;
  box-orient: vertical;
  box-direction: reverse;
}

Explicit distribution

The property box-ordinal-group lets you specify the order in which the boxes will be distributed. This is the ultimate customization opportunity, because you can define the order you want, regardless of the HTML flow order. Those groups are defined by a number starting at 1 (which is the default value). So the box model will first distribute those groups, then all the boxes inside each group. The distribution occurs from the lowest value (the group numbered 1) to the highest (the groups numbered 2 and above).

body {
  display: box;
  box-orient: vertical;
  box-direction : reverse;
}
#box1 {
  box-ordinal-group: 2;
}
#box2 {
  box-ordinal-group: 2;
}
#box3 {
  box-ordinal-group: 1;
}

And what about flexibility?

If changing the natural HTML flow order is huge, the real fun begins when you start to deal with the available space.

Box sizing

By default, a box is not flexible. It becomes flexible only if it has the property box-flex with a value of at least 1.

If a box is not flexible, it will be as wide as possible to make its content visible without any overflow. Its size can be forced with the properties width and height (or their min-*, and max-* alternatives).

If a box is flexible, its size will be computed as follows:

  1. The explicit size declarations (width, height, min-* and max-*)
  2. The size of the parent box and all the remaining available inner space.

So, if the boxes haven’t any size declarations, their sizes will fully depend on their parent box’s size. It will work like this: the size of box is equal to the size of its parent multiplied by the value of the its box-flex property divided by the sum of all the box-flex properties values of all boxes included in its parent.

On the other hand, if one or more boxes have an explicit size statements, the size of all those boxes is computed and all the flexible boxes share the remaining available space on the same principle as above.

It probably sounds a bit tricky, but with some examples it will become easier.

All boxes are flexible

In the next example, box 1 is twice the size of box 2 and box 2 has the same size as box 3. It looks the same as using percentages to set the boxes’ sizes. But there is a big difference. If you add a box, you don’t need to recalculate its size. With the flexible box model, each time you add a box, all the others automatically shrink to make room for the new one.

body {
  display: box;
  box-orient: horizontal;
}
#box1 {
  box-flex: 2;
}
#box2 {
  box-flex: 1;
}
#box3 {
  box-flex: 1;
}

Some boxes have a fixed size

In the next example, box 3, which is not flexible, is 160px in width. In this case, there’s 240px of free space available for boxes 1 and 2. So, box 1 will be 160px in width (240px x 2/3) and box 2 will be 80px in width (240px x 1/3). If you wish, you can make box 3 flexible as well. In this case the way the size of this box is computed will be almost the same as with the property min-width.

body {
  display: box;
  box-orient: horizontal;
  width: 400px;
}
#box1 {
  box-flex: 2;
}
#box2 {
  box-flex: 1;
}
#box3 {
  width: 160px;
}

Managing overflow

Because we can mix flexible boxes, inflexible boxes, and flexible boxes which have preset sizes, It’s possible for the sum of all the boxes’ sizes to be larger or smaller than the parent box size. So you can have too much space or not enough.

I have too much space available; what do I do?

The available space gets distributed depending on the properties box-align and box-pack

The property box-pack manages the way the space is distributed on the horizontal axis and can have one of four possible values: start, end, justify, or center

  1. start: All the boxes are on the left side of the parent box and all the remaining space is on the right side.
  2. end: All the boxes are on the right and the remaining space is on the left
  3. justify: The available space is divided evenly in-between each boxes
  4. center: The available space is divided evenly on each side of the parent box

The property box-align manages the way the space is distributed on the vertical axis and can have one of five values: start, end, center, baseline, and stretch

  1. start: The top edge of each box is placed along the top of the parent box and all the remaining space is placed below.
  2. end: The bottom edge of each box is placed along the bottom of the parent box and all the remaining space is placed above.
  3. center: The available space is divided evenly and placed half above and half below.
  4. baseline: All children are placed with their baselines aligned and the remaining space is placed before or after as necessary (This is a simplification about how this value really works, but you see the point).
  5. stretch: The height of each boxes is adjusted to fit the parent box height

A warning about how those properties work: they are strongly influenced by the use of the properties box-orient and box-direction. They can cause some unexpected behavior (for example, the behavior of values start and end could be fully reversed). I hope that once the specification is finalized, we’ll have more information about how those properties work together.

body {
  display: box;
  box-orient: horizontal;
  /* The content of the body is horizontally centered */
  box-pack: center;
  /* and vertically as well ... \o/ */
  box-align: center;
  width: 100%;
  height : 100%;
}

What happens if I don’t have enough space?

Just like with the traditional box model, the overflow property lets you to define the way it’s managed. No surprise here.

However, you must be careful here too. Indeed, the use of the properties box-orient and box-direction can mess it up. For example, you can see elements overflowed to the right instead of the left or to the top instead of the bottom. Take the time to experiment before trying to use it on a big project or you could go mad.

You can also avoid overflow by making the boxes run over multiple lines (or columns, depending on the orientation) by setting the property box-lines to multiple.

Okay, cool, but does it work in real life?

Yes it does! Both Gecko and WebKit have vendor-prefixed implementations of a box model (Note: The current state of the specification does not reflect Mozilla’s or WebKit’s implementation). This means that Firefox, Safari, Chrome, and any browsers that use one of those rendering engines are able to use the features described in this article. If you use one of those awesome browsers, here is a little demo of the flexible box model in action.

If you’re not using a browser implementing a box model, this screenshot shows you what it looks like:

To conclude

You can start to use this box model to layout your HTML documents with modern web browsers. Be careful though, it’s the really first iteration of a W3C Working Draft. There will certainly be some changes. Anyway, the implementations available in Gecko and Webkit are extremely consistent and mature, so if there are changes, they should not be that troublesome.

This box model is a very easy and simple way to solve some usual problems in web design (form layout, page footers, vertical centering, disassociation of visual flow from HTML flow, etc.). I strongly suggest you become familiar with it because it could become a standard tool for web designers in the near future (if Microsoft decides to include it in IE, it could become so very fast).

What is already available is a good start to play with. But at this point, the way the traditional box model and the flexible box model interact is not very clear (for example, it’s impossible to use position:relative with the properties left or top on a box which uses the property box-ordinal-group). This will be improved, but don’t be surprised if your work habits are somewhat undermined. Another tricky point: the way all the properties relative to this new box model interact can be sometimes really confusing. This should remind you of the day you discovered the float property. ;)

For further information

105 comments

Comments are now closed.

  1. Brett Widmann wrote on December 9th, 2010 at 08:51:

    This is just what I needed! Thanks for sharing.

  2. rodrigo moraes wrote on December 14th, 2010 at 06:26:

    Here’s one schema I created using flexbox. It can make 1 to 3 columns layouts and is very easy to customize:

    http://www.tipfy.org/static/labs/css/flexbox/3_cols.html

    Check the CSS file for a description on how to use it.

  3. κατασκευη ιστοσοσελιδων Websites wrote on February 19th, 2011 at 02:42:

    Too bad I can’t see the example in my browser. Its a very very good model but how about IE? will it work? Thank you

  4. Pingback from CSS3 Flexible Box Model…Layout Coolness…also Oddities & Confusion :: Fleeting Epiphanies on February 24th, 2011 at 21:34:

    [...] demos shown on the Mozilla site appear to work, but in real life really don’t yet work as expected.The demos work because [...]

  5. Marc Diethelm wrote on March 1st, 2011 at 03:39:

    Check http://flexiejs.com/ which iimplements the functionaliy in non-compliant browsers.

    Works like a charm. Since today it’s also available in http://www.cdnjs.com/

  6. Ghigo wrote on March 22nd, 2011 at 10:09:

    I noticed a weird behavior in Firefox when using display: -moz-box in a div with max-height and max-width in an image inside it.

    You can see a test page I just made to make it more clear:
    http://ghigo.strayorange.com/sandbox/box.html

    Hope it could help.
    Thanks for the article.

  7. Eugene wrote on March 23rd, 2011 at 01:18:

    Seems like a bug. I would submit a bug report.

  8. Pingback from CSS3 Tutorials and Resources - WebsitesMadeRight.com on May 16th, 2011 at 20:43:

    [...] The CSS 3 Flexible Box Model (Mozilla Hacks – the Web developer blog | Apr 22, 2010) [...]

  9. Pingback from Step forward with CSS 3 | tutsguru on July 10th, 2011 at 06:45:

    [...] box, but in CSS 3 we have flexible box model. I have found a great tutorial about flexi box. you can read it out. Posted in HTML & CSS « Creating an Attractive Facebook Fan Page You can leave a [...]

  10. Pingback from 55 Best CSS3 Tutorials 2011 | Web Development | iDesignow on July 13th, 2011 at 00:11:

    [...] The CSS 3 Flexible Box Model [...]

  11. Pingback from Flexbox and multiple column layout in CSS3 « Authoring 1 Summer 2011 on July 26th, 2011 at 08:02:

    [...] http://hacks.mozilla.org/2010/04/the-css-3-flexible-box-model/ [...]

  12. Laurent wrote on November 25th, 2011 at 10:42:

    @rodrigo moraes
    Great css. Thanks for sharing it !

  13. JC wrote on November 26th, 2011 at 06:07:

    Sweet! Now, for those of us in digital media and other wide-browser/device-spectrum industries, we just need more browser support (JS fixes are great, but if we used them all at once, it’s a bloating experience).

  14. Eugene wrote on December 8th, 2011 at 06:12:

    justify doesn’t work. post is more than a year old… does it really take that long to fix a bug?

    1. Wes wrote on December 8th, 2011 at 17:08:

      bugs will be not fixed, flexbox will be reimplemented according to the new spec (2011)

      1. Michael C. wrote on December 8th, 2011 at 18:05:

        Well I’d rather it be done right so that we’re all on the same page (no pun intended, really).

        I’m just happy that other browsers (even IE) are implementing this as well. Flexbox et al. are some of the greatest things to happen to CSS since v1. Floats are okay for document-centric pages where flow is of primary importance. But for web APPS, however, other methods must be found and used. I’m considering taking one web app of mine and converting it entirely to use flexbox (already did a quick-and-dirty prototype and it worked perfectly).

        Wes, any idea about the ETA of the new implementation?

        1. Wes wrote on December 8th, 2011 at 23:15:

          since mozilla (firefox, extensions) is heavily based on flexbox, i think new implementation will come very late

          current implementation is not compatible with the new spec, so mozilla has to make to live old implementation and new one together. this is an hard work.

          if mozilla will decide to delete current implementation in favor of the new one, they, probably, have to totally rewrite the xul style declaration.

          so i think (it’s my supposition) that this will not happen soon.

          (p.s. mozilla has the same problem with XBL, i guess)

          1. Michael C. wrote on December 9th, 2011 at 01:12:

            Well they could have 2 modes, one for extensions and another for HTML documents. Then switch modes depending on the context of the viewport content. Yeah, it still means adding an extra leg onto your codebase. But at least it can be kept manageable. They can deprecate the old interface, too, so that maintenance is no longer an issue. Guess that’s the price to pay for constructing so much atop a moving standard.

  15. Pingback from 23 Must-Read Tutorials for Advanced HTML5/CSS3 Coders | Top website Designing Company in India on December 16th, 2011 at 17:27:

    [...] CSS3 Flexible Box Model [...]

  16. φωτοβολταικα wrote on December 23rd, 2011 at 04:24:

    I use mozilla (the newest version) and cant see how flexible box model working. I just watch the demo and nothing… Why?

  17. pd wrote on January 3rd, 2012 at 06:47:

    Isn’t it just depressing to read an article like this, now over 18 months old, and realize that we still cannot use the only sensiible box layout model ever design for the web (which itself has come ridiculously late being some 15 years or more since the invention of the web!)?

    If only Microsoft wasn’t trying to leverage IE to encourage updrading from XP. Alas, even with Microsoft now force-upgrading users to the latest IE available for their Windows version, their decision not to port IE9 onwards to XP is a killer.

  18. αποκριατικες στολες wrote on January 11th, 2012 at 05:09:

    IE is always two or three steps behind mozilla and chrome. I think that they dont care about the browser…

  19. garra rufa fish spa wrote on January 16th, 2012 at 11:22:

    If you want to use something real good, use safari. Its like apple, just perfect!

  20. Pingback from CSS3 Esnek Kutu Yerleşimi(Flexible Box Layout) | Orkun Altunbay on March 3rd, 2012 at 04:41:

    [...] http://hacks.mozilla.org/2010/04/the-css-3-flexible-box-model/ [...]

  21. Jean-Yves Perrier wrote on April 25th, 2012 at 17:05:

    I don’t know where you are testing this, but the modern flexbox specification uses property names starting with flex-* and no more with box-*.

    If you are trying this by adding the -moz prefix to the box-* described here, you are very lucky to have something working fine. The -moz-box-* is not these properties but a XUL flexible box model which is fairly different (it was one of the experimental to create the Flexbox model).

    In both case, you shouldn’t build any websites using these two outdated models, it will either work in Firefox only (the -moz-box-* case) or suddenly stop working when browsers will drop it once they have finished implementing the latest spec.

  22. κατασκευή ιστοσελίδων wrote on June 19th, 2012 at 04:05:

    Jean Yves you have lot of knowledge. Are you a designer in France?

  23. sean wrote on June 22nd, 2012 at 10:36:

    What is the best way to deal with tables when using flex box model? When I tried using this, content was horribly distributed, of course, because flex defaults to box-orient: horizontal. And even if you change it to vertical, that’s no good, assuming all elements are displayed in flexbox. What I’ve discovered so far is that tables are meant to be displayed in table format, and not flex. But it doesn’t seem to be resizing properly even with normal, table display.

  24. φωτοβολταικα wrote on June 26th, 2012 at 23:17:

    maybe we ll have to waiting for IE 11 :)

  25. ashish wrote on August 12th, 2012 at 23:26:

    really I.E creating very big issue but this article is very useful thx for this.

  26. chrixian wrote on October 26th, 2012 at 23:31:

    Maybe use a real browser

  27. πλαστικός χειρουργός wrote on November 14th, 2012 at 15:43:

    Why this simple code cant play to my I.E.? I hate to say that but I.E. sucks! Start right now using Chrome.

  28. εξωσωματική γονιμοποίηση wrote on January 30th, 2013 at 02:00:

    Great css. Thanks for it !

1 2

Comments are closed for this article.