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:

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

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).

  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

About Paul Rouget

Paul is a Firefox developer.

More articles by Paul Rouget…


  1. Brett Widmann

    This is just what I needed! Thanks for sharing.

    December 9th, 2010 at 08:51

  2. rodrigo moraes

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

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

    December 14th, 2010 at 06:26

  3. κατασκευη ιστοσοσελιδων Websites

    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

    February 19th, 2011 at 02:42

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

    February 24th, 2011 at 21:34

  5. Marc Diethelm

    Check which iimplements the functionaliy in non-compliant browsers.

    Works like a charm. Since today it’s also available in

    March 1st, 2011 at 03:39

  6. Ghigo

    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:

    Hope it could help.
    Thanks for the article.

    March 22nd, 2011 at 10:09

  7. Eugene

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

    March 23rd, 2011 at 01:18

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

    May 16th, 2011 at 20:43

  9. […] 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 […]

    July 10th, 2011 at 06:45

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

    July 13th, 2011 at 00:11

  11. […] […]

    July 26th, 2011 at 08:02

  12. Laurent

    @rodrigo moraes
    Great css. Thanks for sharing it !

    November 25th, 2011 at 10:42

  13. JC

    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).

    November 26th, 2011 at 06:07

  14. Eugene

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

    December 8th, 2011 at 06:12

    1. Wes

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

      December 8th, 2011 at 17:08

      1. Michael C.

        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?

        December 8th, 2011 at 18:05

        1. Wes

          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)

          December 8th, 2011 at 23:15

          1. Michael C.

            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.

            December 9th, 2011 at 01:12

  15. […] CSS3 Flexible Box Model […]

    December 16th, 2011 at 17:27

  16. φωτοβολταικα

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

    December 23rd, 2011 at 04:24

  17. pd

    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.

    January 3rd, 2012 at 06:47

  18. αποκριατικες στολες

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

    January 11th, 2012 at 05:09

  19. garra rufa fish spa

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

    January 16th, 2012 at 11:22

  20. […] […]

    March 3rd, 2012 at 04:41

  21. Jean-Yves Perrier

    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.

    April 25th, 2012 at 17:05

  22. κατασκευή ιστοσελίδων

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

    June 19th, 2012 at 04:05

  23. sean

    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.

    June 22nd, 2012 at 10:36

  24. φωτοβολταικα

    maybe we ll have to waiting for IE 11 :)

    June 26th, 2012 at 23:17

  25. ashish

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

    August 12th, 2012 at 23:26

  26. chrixian

    Maybe use a real browser

    October 26th, 2012 at 23:31

  27. πλαστικός χειρουργός

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

    November 14th, 2012 at 15:43

  28. εξωσωματική γονιμοποίηση

    Great css. Thanks for it !

    January 30th, 2013 at 02:00

Comments are closed for this article.