Grow your CSS skills. Land your dream job.

Last updated on:

A Complete Guide to Flexbox


The Flexbox Layout (Flexible Box) module (currently a W3C Candidate Recommendation) aims at providing a more efficient way to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic (thus the word "flex").

The main idea behind the flex layout is to give the container the ability to alter its items' width/height (and order) to best fill the available space (mostly to accommodate to all kind of display devices and screen sizes). A flex container expands items to fill available free space, or shrinks them to prevent overflow.

Most importantly, the flexbox layout is direction-agnostic as opposed to the regular layouts (block which is vertically-based and inline which is horizontally-based). While those work well for pages, they lack flexibility (no pun intended) to support large or complex applications (especially when it comes to orientation changing, resizing, stretching, shrinking, etc.).

Note: Flexbox layout is most appropriate to the components of an application, and small-scale layouts, while the Grid layout is intended for larger scale layouts.

Basics & Terminology

Since flexbox is a whole module and not a single property, it involves a lot of things including its whole set of properties. Some of them are meant to be set on the container (parent element, known as "flex container") whereas the others are meant to be set on the children (said "flex items").

If regular layout is based on both block and inline flow directions, the flex layout is based on "flex-flow directions". Please have a look at this figure from the specification, explaining the main idea behind the flex layout.

Basically, items will be laid out following either the main axis (from main-start to main-end) or the cross axis (from cross-start to cross-end).

  • main axis - The main axis of a flex container is the primary axis along which flex items are laid out. Beware, it is not necessarily horizontal; it depends on the flex-direction property (see below).
  • main-start | main-end - The flex items are placed within the container starting from main-start and going to main-end.
  • main size - A flex item's width or height, whichever is in the main dimension, is the item's main size. The flex item's main size property is either the ‘width’ or ‘height’ property, whichever is in the main dimension.
  • cross axis - The axis perpendicular to the main axis is called the cross axis. Its direction depends on the main axis direction.
  • cross-start | cross-end - Flex lines are filled with items and placed into the container starting on the cross-start side of the flex container and going toward the cross-end side.
  • cross size - The width or height of a flex item, whichever is in the cross dimension, is the item's cross size. The cross size property is whichever of ‘width’ or ‘height’ that is in the cross dimension.

Properties for the Parent
(flex container)


This defines a flex container; inline or block depending on the given value. It enables a flex context for all its direct children.

.container {
  display: flex; /* or inline-flex */

Note that CSS columns have no effect on a flex container.


This establishes the main-axis, thus defining the direction flex items are placed in the flex container. Flexbox is (aside from optional wrapping) a single-direction layout concept. Think of flex items as primarily laying out either in horizontal rows or vertical columns.

.container {
  flex-direction: row | row-reverse | column | column-reverse;
  • row (default): left to right in ltr; right to left in rtl
  • row-reverse: right to left in ltr; left to right in rtl
  • column: same as row but top to bottom
  • column-reverse: same as row-reverse but bottom to top


By default, flex items will all try to fit onto one line. You can change that and allow the items to wrap as needed with this property. Direction also plays a role here, determining the direction new lines are stacked in.

  flex-wrap: nowrap | wrap | wrap-reverse;
  • nowrap (default): single-line / left to right in ltr; right to left in rtl
  • wrap: multi-line / left to right in ltr; right to left in rtl
  • wrap-reverse: multi-line / right to left in ltr; left to right in rtl

flex-flow (Applies to: parent flex container element)

This is a shorthand flex-direction and flex-wrap properties, which together define the flex container's main and cross axes. Default is row nowrap.

flex-flow: <‘flex-direction’> || <‘flex-wrap’>


This defines the alignment along the main axis. It helps distribute extra free space left over when either all the flex items on a line are inflexible, or are flexible but have reached their maximum size. It also exerts some control over the alignment of items when they overflow the line.

.container {
  justify-content: flex-start | flex-end | center | space-between | space-around;
  • flex-start (default): items are packed toward the start line
  • flex-end: items are packed toward to end line
  • center: items are centered along the line
  • space-between: items are evenly distributed in the line; first item is on the start line, last item on the end line
  • space-around: items are evenly distributed in the line with equal space around them


This defines the default behaviour for how flex items are laid out along the cross axis on the current line. Think of it as the justify-content version for the cross-axis (perpendicular to the main-axis).

.container {
  align-items: flex-start | flex-end | center | baseline | stretch;
  • flex-start: cross-start margin edge of the items is placed on the cross-start line
  • flex-end: cross-end margin edge of the items is placed on the cross-end line
  • center: items are centered in the cross-axis
  • baseline: items are aligned such as their baselines align
  • stretch (default): stretch to fill the container (still respect min-width/max-width)


This aligns a flex container's lines within when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis.

Note: this property has no effect when there is only one line of flex items.

.container {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
  • flex-start: lines packed to the start of the container
  • flex-end: lines packed to the end of the container
  • center: lines packed to the center of the container
  • space-between: lines evenly distributed; the first line is at the start of the container while the last one is at the end
  • space-around: lines evenly distributed with equal space between them
  • stretch (default): lines stretch to take up the remaining space

Properties for the Children
(flex items)


By default, flex items are laid out in the source order. However, the order property controls the order in which they appear in the flex container.

.item {
  order: <integer>;


This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.

If all items have flex-grow set to 1, every child will set to an equal size inside the container. If you were to give one of the children a value of 2, that child would take up twice as much space as the others.

.item {
  flex-grow: <number>; /* default 0 */

Negative numbers are invalid.


This defines the ability for a flex item to shrink if necessary.

.item {
  flex-shrink: <number>; /* default 1 */

Negative numbers are invalid.


This defines the default size of an element before the remaining space is distributed.

.item {
  flex-basis: <length> | auto; /* default auto */


This is the shorthand for flex-grow, flex-shrink and flex-basis combined. The second and third parameters (flex-shrink and flex-basis) are optional. Default is 0 1 auto.

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]


This allows the default alignment (or the one specified by align-items) to be overridden for individual flex items.

Please see the align-items explanation to understand the available values.

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;

Note that float, clear and vertical-align have no effect on a flex item.


Let's start with a very very simple example, solving an almost daily problem: perfect centering. It couldn't be any simpler if you use flexbox.

.parent {
  display: flex;
  height: 300px; /* Or whatever */

.child {
  width: 100px;  /* Or whatever */
  height: 100px; /* Or whatever */
  margin: auto;  /* Magic! */

This relies on the fact a margin set to `auto` in a flex container absorb extra space. So setting a vertical margin of auto will make the item perfectly centered in both axis.

Now let's use some more properties. Consider a list of 6 items, all with a fixed dimensions in a matter of aesthetics but they could be auto-sized. We want them to be evenly and nicely distributed on the horizontal axis so that when we resize the browser, everything is fine (without media queries!).

.flex-container {
  /* We first create a flex layout context */
  display: flex;
  /* Then we define the flow direction and if we allow the items to wrap 
   * Remember this is the same as:
   * flex-direction: row;
   * flex-wrap: wrap;
  flex-flow: row wrap;
  /* Then we define how is distributed the remaining space */
  justify-content: space-around;

Done. Everything else is just some styling concern. Below is a pen featuring this example. Be sure to go to CodePen and try resizing your windows to see what happen.

Check out this Pen!

Let's try something else. Imagine we have a right-aligned navigation on the very top of our website, but we want it to be centered on medium-sized screens and single-columned on small devices. Easy enough.

/* Large */
.navigation {
  display: flex;
  flex-flow: row wrap;
  /* This aligns items to the end line on main-axis */
  justify-content: flex-end;

/* Medium screens */
@media all and (max-width: 800px) {
  .navigation {
    /* When on medium sized screens, we center it by evenly distributing empty space around items */
    justify-content: space-around;

/* Small screens */
@media all and (max-width: 500px) {
  .navigation {
    /* On small screens, we are no longer using row direction but column */
    flex-direction: column;
Check out this Pen!

Let's try something even better by playing with flex items flexibility! What about a mobile-first 3-columns layout with full-width header and footer. And independent from source order.

.wrapper {
  display: flex;
  flex-flow: row wrap;

/* We tell all items to be 100% width */
.header, .main, .nav, .aside, .footer {
  flex: 1 100%;

/* We rely on source order for mobile-first approach
 * in this case:
 * 1. header
 * 2. nav
 * 3. main
 * 4. aside
 * 5. footer

/* Medium screens */
@media all and (min-width: 600px) {
  /* We tell both sidebars to share a row */
  .aside { flex: 1 auto; }

/* Large screens */
@media all and (min-width: 800px) {
  /* We invert order of first sidebar and main
   * And tell the main element to take twice as much width as the other two sidebars 
  .main { flex: 2 0px; }
  .aside-1 { order: 1; }
  .main    { order: 2; }
  .aside-2 { order: 3; }
  .footer  { order: 4; }
Check out this Pen!

Prefixing Flexbox

Flexbox requires some vendor prefixing to support the most browsers possible. It doesn't just include prepending properties with the vendor prefix, but there are actually entirely different property and value names. This is because the Flexbox spec has changed over time, creating an "old", "tweener", and "new" versions.

Perhaps the best way to handle this is to write in the new (and final) syntax and run your CSS through Autoprefixer, which handles the fallbacks very well.

Alternatively, here's a Sass @mixin to help with some of the prefixing, which also gives you an idea of what kind of things need to be done:

@mixin flexbox() {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;

@mixin flex($values) {
  -webkit-box-flex: $values;
  -moz-box-flex:  $values;
  -webkit-flex:  $values;
  -ms-flex:  $values;
  flex:  $values;

@mixin order($val) {
  -webkit-box-ordinal-group: $val;  
  -moz-box-ordinal-group: $val;     
  -ms-flex-order: $val;     
  -webkit-order: $val;  
  order: $val;

.wrapper {
  @include flexbox();

.item {
  @include flex(1 200px);
  @include order(2);

Related Properties

Other Resources

Browser Support

Broken up by "version" of flexbox:

  • (new) means the recent syntax from the specification (e.g. display: flex;)
  • (tweener) means an odd unofficial syntax from 2011 (e.g. display: flexbox;)
  • (old) means the old syntax from 2009 (e.g. display: box;)
Chrome Safari Firefox Opera IE Android iOS
21+ (new)
20- (old)
3.1+ (old)
6.1+ (new)
2-21 (old)
22+ (new)
12.1+ (new) 10 (tweener)
11+ (new)
2.1+ (old)
4.4+ (new)
3.2+ (old)
7.1+ (new)

Blackberry browser 10+ supports the new syntax.

For more informations about how to mix syntaxes in order to get the best browser support, please refer to this article (CSS-Tricks) or this article (DevOpera).


  1. Yay. Less javascript and more CSS. What’s not to like? Great info, as always!

    • Permalink to comment#

      Flexbox its fine, but It is still not valid for a simple perfect “product grid” with no margins at first and last elements in row, and left aligned. Otherwise: could you build this layout using flexbox? thanks

    • @Alex Yes, you can. In the same manner that you do so with non-flex grids, apply a negative margin-left to the grid wrapper, and apply that same value as padding left to all grid columns.

      .grid { margin-left: -20px;}
          .grid__col { padding-left: 20px;}

      Look at for how it’s done with inline-block elements, which allows you to apply vertical alignment to columns, too.

    • mystrdat
      Permalink to comment#

      @Alex @Lawrence That has little do with flexbox itself. .el:not(:last-of-type) and similar exclusion selectors. Negative margins are rubbish.

    • @mystrdat You’re correct, it has nothing to do with flexbox. Using :not selectors, however, will be unscalable, and you will lose IE8 support (less of an issue now).

      If I have a grid with 8 items, each occupying 25% of the width, that technique fails, since the 4th item will not sit flush with the container edges.

      If I have a grid with 4 items, 25% width on desktop, and then 50% width on mobile, that technique fails again, for the above reason. How about managing 3rds, 5ths, 6ths, 12fths, etc., and when columns change to use different widths across viewports?

      I wouldn’t call negative margins rubbish. Perhaps not ideal, but they solve a complex problem elegantly.

    • Yazin
      Permalink to comment#

      @Alex .. actually, it’s alot simpler. Just use

      justify-content: space-between;

      More here

  2. Jacob Dubail
    Permalink to comment#

    Hey Chris,

    Thank you so much for the comprehensive write up.

    I just updated Firefox to v20 on a mac and now all of the flex-box demos aren’t working. Everything still looks great in Chrome.

    Anyone else having this problem?

  3. Coolcat007
    Permalink to comment#

    The only thing I don’t understand is why the use of prefixes is needed if the syntax doesn’t differ from the recommendation.

    I think what would be enough is (using the above example):

    .wrapper {
      display: -webkit-box;
      display: -moz-box;
      display: -ms-flexbox;
      display: flex;
    .item {
      -webkit-box-flex: 1 200px;
      -moz-box-flex:  1 200px;
      flex:  1 200px;
      -webkit-box-ordinal-group: 2;  
      -moz-box-ordinal-group: 2;     
      -ms-flex-order: 2;     
      order: 2;

    At the moment this is not supported, but I think it should be because everything that was left out here had the recommended syntax. The prefixes still should be available if needed, but it shouldn’t be necessary.

  4. Daniel
    Permalink to comment#

    Regarding the example with the 6 items of fixed dimensions to be evenly distributed – using the
    justify-content: space-around; rule:

    I’d really like to use this, however it’s not doing exactly what I want. Let’s say there’s only room for 4 of the items on the first row, the remaining 2 will be evenly spaced on the second row. (ughh)

    Is there any way for items on the last row to be placed/aligned underneath the elements from the previous row (left->right)??

    • Coolcat007
      Permalink to comment#

      This is something that can be done with the grid layout module, but it is not supported by the browsers yet.

      You could always use tables and calc()

    • Daniel
      Permalink to comment#

      @Coolcat007 You mention that this can be done with tables and calc() – is this so – even if you have a dynamic number of items?? If it is – any chance of a fiddle / codepen?


  5. Coolcat007
    Permalink to comment#

    Sorry, I misunderstood your question. For a dynamic number of items, this won’t work without JS or php.
    This is indeed a thing that could be added.
    Something like align-items:main-axis /cross-axis could be a great addition.

  6. I think the browser support table is missing a cell, the one with Opera’s version 12.1+.

    The table, as it is now, shows “Any” for IE. It’s funny! :)

  7. Tim McKay
    Permalink to comment#

    Works beautifully in Chrome and Safari, but I’m on FireFox (v21) and it’s not working well at all. It doesn’t allow the paragraphs to break. It’s like it’s treating the display:flex as display:inline-flex. The only way I’ve been able to get around this is to change the about:config of Firefox to multiline, but visitors won’t have that set by default.

    Has anyone had any luck with this? Currently I’m using flexbox for webkit and equalize.js for other browsers.

    • Coolcat007
      Permalink to comment#

      I think that’s because flexbox isn’t fully supported by firefox until v22. That’s why I’m running the v22 beta at the moment. You can always use the display:box untill ff22 is released.

  8. Am I crazy enough if I use this in production? I have a really awkward situation and I can’t use display: table. It messes up with the fluidity of the images.

    • Kevin L.
      Permalink to comment#

      You can use flexbox in production pretty well as long as you’re using a sound way to detect less-than-ideal support for flex-wrap w/ modernizer and use a ratio-based grid system like Singularitygs as a fallback.

      An example: (toggle the flexbox and .noflex option.

      It’s a sound strategy to the extent you can use flexbox first towards planning for the layout and quickly create the fallback with a ratio-based grid system.

      As long as you’re considerate enough to have a style guide that documents documenting how a particular component ought to look if it in facts differs from both, you should be fine.

  9. Permalink to comment#

    Flexbox is now unprefixed in Firefox (22).

  10. I found a compass compatible mixins

  11. tinabeans
    Permalink to comment#

    In your second Codepen example (with the blue navigation bar), I couldn’t figure out why the flow-direction: column doesn’t seem to kick in at the smallest screen width. I played around with a few values and found that explicitly adding some height to the ul.navigation made the li’s stack vertically. Is there a better way around this without requiring a hard-coded height?

    • Jay

      That’s because the code for max 600 width is missing a flex-flow: column wrap; if you are using firefox. It only contains one for web-kit. Once I added that in, it does it nicely in my FF.

  12. skitterm
    Permalink to comment#

    Thanks for the post. I found it highly insightful.

  13. Ankur Oberoi
    Permalink to comment#

    Something weird is going on in the first example’s pen ( I tried recreating it on CodePen and noticed it wasn’t working, even when I copied and pasted! Then I tried recreating it locally, copied and pasted, and again it didn’t work. So then I took to the Chrome DevTools to take a look at what was going on and it looks like even though the pen uses the rule justify-content: space-around;, what is actually rendered on the page is -webkit-justify-content: space-around;. Turns out prefix-free was turned on in the CodePen config for the Scss panel.

    Even if this was CodePen’s prefix-free doing the work for me, mixing vendor prefixed rules and non-prefixed rules that the preprocessor transforms should be a no-no.

  14. Ionut
    Permalink to comment#

    Thanl you for the mixin’ Chris

  15. Nice post Chris. I like how thorough and detailed you are. Too bad we don’t use SASS, we rely almost solely on LESS. We would love to use Flexbox for clients, but it doesn’t seem to play nicely cross browser. I checked this page in FF22 and IE10 and it was a mess.

    Do you, or anyone else, know of any good JS polyfills or plugins or solutions to get this to play cross-browser nicely? Otherwise, how long (in your opinion) until we can ‘realistically’ use this without a lot of cross browser headaches?

  16. Dario Grassi
    Permalink to comment#

    Great post Chris. I think that flexbox capability to order items will be usefull in RWD.

    I’ve got only a question. When you define main-axis you say that its direction depends on the justify-content property, but isn’t the flex-direction property that defines if flex items are layed out as a row or as a column? Am I misunderstanding something?

    • When you define main-axis you say that its direction depends on the justify-content property, but isn’t the flex-direction property that defines if flex items are layed out as a row or as a column?

      You’re correct, that was wrong in the article and is fixed now.

  17. ZippZipp
    Permalink to comment#

    Hey, anybody knows real site that using flexbox?

    I know that SM try to use it some time ago, but returns to floats.

  18. Permalink to comment#

    main axis – The main axis of a flex container is the primary axis along which flex items are laid out. Beware, it is not necessarily horizontal; it depends on the justify-content property (see below).

    I think you mean flex-direction.

    flex-direction (Applies to: parent flex container element)

    flex-direction: row | row-reverse | column | column-reverse
    row (default): left to right in ltr; right to left in rtl
    row-reverse: right to left in ltr; left to right in rtl
    column: same as row but top to bottom
    column-reverse: same as row-reverse but top to bottom

    I think in column-reverse you mean but bottom to up

  19. sam
    Permalink to comment#

    Thanks very thorough explanation

  20. SelenIT
    Permalink to comment#

    Firefox 22+ has unprefixed Flexbox, but, unfortunately, it still doesn’t support flex-wrap property (and hence flex-flow shorthand). So the wonderful example with 3-column layout reducing to 1 column on narrow screen in Firefox looks really messy. But it’s possible to create its simplified analog that works in both Chromium-based browsers and Firefox 23+:

  21. Permalink to comment#

    Wow, its really the one the best post i ever read on this topic. The steps which you have mentioned are really perfect.

  22. Arthur
    Permalink to comment#

    Hey, Cris! Looks like “flex-wrap” incorrectly works in Firefox and Opera! Both tomato blocks and very last demoes do not work!
    Is there some workaround already?

    And thank you so much for your website! ;)

    • Permalink to comment#

      Yes, only latest Chromium-based browsers like Chrome, Opera 16+ etc. seem to support multi-line flexboxes currently. As a workaround, you can use nested flexboxes in combination with media queries, as in my comment above (it’s not so flexible as true multi-line flexboxes, but still better than nothing) or use graceful degradation to old techniques like inline-blocks.

  23. Permalink to comment#

    I’ve found that, in Chrome 29, <input /> and <label> do not respect order. Anyone else observed this, or have an idea as to why?

  24. Permalink to comment#

    Flexbox is what CSS has been sorely lacking since its inception – an easy way to create flexible web page layouts without the need for floats, clears, margin: 0 auto and JS hacks. I look forward to the day when flexbox is supported by a big enough share of the browser market to put into this all of our production sites.

  25. Aron Duby
    Permalink to comment#

    Thanks for the awesome tutorial, just managed to use the knowledge to make a sweet way to build tournament brackets! You can check out the codepen at

  26. I find myself doing a Mr. Burns “excellent”, as I’m pretty excited about align-items: stretch

  27. I am trying to make my video rich website “FLEX”. The site scales ok but the Vimeo iframe videos do not.
    I was trying to use the FitVids.js script to make this work but I am not sure how to make that work with my Weebly template. (YES I am not a website professional, I know nothing about CSS or HTML) But I have been tasked with this job and I need to make it work properly. Any help would be appreciated. Using Firebug plug in the Firefox browser I saw this code about Flex Box… How do I modify this to make the videos Flex?

    > `  <!DOCTYPE html>
        <html class="new-editor js no-flexbox flexbox-legacy canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients no-cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">
        <body id="body" class="wsite-editor allow-collapse-transition">
  28. Permalink to comment#

    column-reverse: same as row-reverse but top to bottom

    Don’t you mean bottom to top?

  29. Reblutus
    Permalink to comment#

    I really like this post. It got me started with my project.

    i had a problem with firefox like other users here but came over it by wrapping the columns/rows in more container like a user suggested.

    I have another problem though. This time it’s with IE11. If you look at your example of the menu, you will see that on the smallest width the menus are not shown in columns and stays as rows.

    On my side I had a different problem with IE: the columns were showing but the items in them had no height! So everything collapses for no reason. Of course it’s fine in Chrome and Firefox (25)

  30. Britton
    Permalink to comment#

    There is a typo with the portion on flex grow. It doesn’t inhibit understanding the content, but it would be nice if you fix it.

  31. Jesse
    Permalink to comment#

    The W3C needs to get off their a** and push this through. A consistent browser implementation will make life so much easier for creating layouts.

  32. Jesse
    Permalink to comment#

    Am I the only one that thinks this ‘article’ should be in the “article” section?

  33. Permalink to comment#

    Chris, I couldn’t vertically align some content in print media, do you know where I could find more information about this kind of support?

    My test looks something like this,


    @page {
        size: US-Letter;
    article {
        page-break-after: always;
        text-align: center;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;
    article:last-child {
        page-break-after: avoid;


                Hello 2
    • Carlos
      Permalink to comment#

      Not all browsers support paged media, does the paged media example work without the flexbox?

  34. Michele
    Permalink to comment#

    What does 22+ (new), in the Firefox support table means?

  35. Oron
    Permalink to comment#

    One of the best article I have ever read. Thanks!

  36. Andy
    Permalink to comment#

    Nice tutorial. Has anything changed this this tutorial was published?
    Also it doesn’t work for me in IE10.

  37. Mark
    Permalink to comment#

    Great article. I found it helpful to see what is coming along the horizon. The company I contract for right now uses IE8 so I have to wait until they move to newer version of IE. I have always wondered why a good layout system has been missing from CSS. Better late than never I guess. I look forward to using this on touch devices with webkit.

  38. Dennis
    Permalink to comment#

    Nice work man!!!

  39. Brad Spencer
    Permalink to comment#

    Having trouble with 2 flexboxes aligned horizontally when one is set in column flow and the other in column-reverse flow.

    See pen: Flexbox Alignment Sample

    How do I fix this? Thanks!

  40. Felix
    Permalink to comment#

    Chris, your embedded Codepen demo is broken, perhaps because of the new rendering engine update on Codepen? Just my assumption :p. Anyways great article, it helps me a lot! Thanks…
    This is the error on the embedded codepen
    {"success":false,"errors":{"error":["Load on secure subdomain."]},"status":200}

  41. Jan
    Permalink to comment#


    in your first example, the child element has been centered by (magic!) margin: auto;

    This solution does not work in IE11 if the child element has no defined height, for example, if the height is determined by the content.

    All other browsers behave as expected.

    .parent {
    display: flex;
    height: 300px; /* Or whatever */

    .child {
    width: 100px; /* Or whatever /
    height: 100px; /
    Or whatever / —- Doesn’t work in IE11, if the height is determined by the content —-
    margin: auto; /
    Magic! */

  42. Matt MacLaurin
    Permalink to comment#

    Your definition of “main axis” has a bug: you say it’s dependent on justify-content but I think you mean to say it’s dependent on flex-direction.

  43. Permalink to comment#

    I messed with this a bit today. I’m interested but a bit confused at the same time. If I code it (literally copy it) from what you have here to CodePen it runs as yours did. If, however, I try that on JSFiddle ( where I normally mess around ) the colors come out in a straight line only. Also, if I load the entire page via jQuery, as I’ve been doing lately, the same result… Instead of the framed environment you’re getting I received flat little lines. I’ve even tried injecting the CSS into the Header before building the page via jQuery with much the same result. Seems that this only works without jQuery and for whatever reason only on CodePen.

  44. Permalink to comment#

    Would you happen to know how I could code in a horizontal split ( like they have on Code Pen ) that separates the top of the window and the bottom of the window and moves fluidly when the bar is moved, with flexbox framework? Any help would be appreciated, thanks!

    • The draggable bar isn’t going to happen with just CSS, flexbox or no, save for some super crazy hack using a resizeable textarea or something. On CodePen we use jQuery UI draggable, but there are others out there. Flexbox does make the situation easier though. One time I redid the whole CodePen editor layout in Flexbox for fun and it was way easier, but of course I can’t find it now. Basically if the flex items have flex: 1; they will fill the area, so you just resize one of them to a specific height (or width) and the other will fill the remaining space. So no math.

    • Permalink to comment#

      Do you know of any working examples of jQuery UI Draggable for a horizontal split pane? I’ve been messing with it for a couple of days now and can’t seem to figure it out.

  45. Gimm
    Permalink to comment#

    Hi Chris,
    I’m trying to make a div which its width auto grow with its contents.
    Using this:

    display: inline-flex;
    flex-flow: column wrap;

    There seems a bug that with the container’s main size, please see this pen
    wrong main size when flex-driection is column

  46. John
    Permalink to comment#

    This is just beyond comprehension

  47. anon
    Permalink to comment#

    I found this article confusing. I’m a frontend developer and still couldn’t understand a single term that was used to explain what I was looking at.

    • coolcat007
      Permalink to comment#

      Thats weird, I’m an amature and I could read it with ease.

  48. Mark F. Simchock
    Permalink to comment#

    Well played. Thanks Chris.

    This will certainly be a great tool to have once it’s better supported. For now it seems to me it’s best to lean on js, or just stick to a design / layout that can be manufactured with less-buggy (if you will) off the shelf parts.

    If design doesn’t consider manufacturing then that’s not design. That’s art. There’s a difference.

  49. This is like a CSS angle pissing on my tongue. Awesome.

  50. Evert
    Permalink to comment#

    Perhaps not the best place to ask, but I am struggling with making a responsive flexbox fluid layout. What I want is 3 breakpoints like this:
    1) 3 rows (containers vertical, small screen)
    2) 2 columns, 2 rows (medium screen)
    3) 3 columns (large screen)
    1 en 3 are easy, I just change the flex-direction from column to row. But how about 2)?
    So basically it must look like:


    A B

    A B C

    • Evert
      Permalink to comment#

      Gonna answer my own question. The reason I could not get it to work is because IE11 does not like a max-width to be set on any flex-item. If you do, it wrongly calculates the space around or between the items.

  51. Jon
    Permalink to comment#

    Great article, thanks. Regarding the the browser support table, I think that IE11 may have full support of the specification.

  52. Dwayne
    Permalink to comment#

    Does using flexbox responsibly meaning coding the site via flexbox and usual css positioning methods as a fall back for browsers who dont support flexbox, coding the layout twice? Just thinking workflow wise…

  53. Thanks Chris! This is an excellent Flexbox reference. I have implemented a basic Holy Grail template: Flexbox is a thing of beauty!

  54. Anton G
    Permalink to comment#

    Nice Job!.

    Thanks for sharing this.

    I found this Polyfill for flexbox,

  55. Evert
    Permalink to comment#

    Things I noticed using flexbox that are a real pain:

    Using margin: 0 auto; on the flex-container shrinks the container (and it’s containing flex-items) to the minimum width. It is no longer flexible/fluid.
    Because of this, any fluid, centered layout must use justify-content: center/ or space-between. But then the layout becomes “infinite” (you can make the screen wider and wider and the boxes and spaces will happily distribute themselves across that space possibly breaking any design restrictions). So in order to prevent that we could set max-width on the flex container, but that cancels out the centering for some reason and the page flushes left. So the only other possibility is to set a max-width on one or more flex-items…but those will break in IE11 because of some bug.
    In short: flexbox will only work practically when using the full screen width and not limiting any flexible item with a max-width. As soon as you want to set a limit to any item, it falls apart.

  56. fred
    Permalink to comment#

    I too see no other advantage for this than limiting some lines in my media queries

  57. Stuart
    Permalink to comment#

    This really annoyed me and was broken for a bit, so I wanted to share in case anyone ever comes across this in the future. If you need to support blackberry 7+, make sure you use

    -webkit-box-orient: vertical;
    -moz-box-orient: vertical;
    -webkit-box-direction: normal;
    -moz-box-direction: normal;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;

    …if you use row wrap, it doesn’t wrap and just puts everything side-by-side. Also, very important. Make sure the child elements of the parent flex container don’t have display: inline; applied to them. It breaks it for some reason. I hope this helps someone!

    • Stuart
      Permalink to comment#

      One last important thing to remember if you have to support blackberry 7+…make sure all child elements have float:none applied to them…if floats are applied, they’ll just not appear. I hope this helps!

  58. Ed
    Permalink to comment#

    In the first line of the SASS mixin, shouldn’t @mixin flexbox() be just @mixin flexbox?

  59. Deepak
    Permalink to comment#

    Chris, this example does not work in IE11

    could you please suggest, how I can have support on IE11

    • Chris
      Permalink to comment#

      The .wrapper defined “-webkit-flex-flow: row wrap;” only, add “flex-flow: row wrap;” and it works in IE 11 and Firefox.

  60. Najmul
    Permalink to comment#

    Where are things:

    • Those are deprecated properties. I feel like it’s best at this point (at least in terms of this guide) to focus on the current properties. Also best in practice to let a tool like Autoprefixer deal with inserting those older properties for you when needed.

  61. Amazing writeup and excellently explained, you saved me fairly a LOT of time I would off spent learning all this combining all the broken and outdated articles over the web :D thank you so much !

  62. Scott
    Permalink to comment#

    This is a great article. I’d love to see the pens using the flex wrap updated with “flex-flow: row wrap;” added un-prefixed so they work in Firefox 29! But still a very good and informative article.

  63. Larry
    Permalink to comment#

    Chris I really need this. Thanks!

  64. Gluten
    Permalink to comment#

    Is there a way to specify a minimum for inter-elements spacing when using flex-wrap: wrap;? The only way I’ve currently found forces me to add a padding to the container which isn’t ideal.

  65. Ceah

    Please forgive my newbie ignorance.

    I’m thinking that I would experiment with a background color of the site, then the container would be another color (centered) and then the flex items yet another color.

    I get how to center the flex items themselves, but how would you center the container itself? And is that something one would even want to do?


    • Ceah

      margin: 0px auto;

      think I figured it out….feel very dumb right now!

  66. Guilherme Bruzzi

    Hi Chris! Very nice article! But the last example “mobile-first 3-columns layout with full-width header and footer” in my 34.0.1847.131 chrome didn’t make the two sidebars half of the size of the main content.
    I had to write:
    @media all and (min-width: 800px) {
    .aside-1 { order: 1; flex: 1 25%; }
    .main { order: 2; flex: 2 1 50%; }
    .aside-2 { order: 3; flex: 1 25%; }
    .footer { order: 4; }
    On the last media query in order to do that ( ).

  67. johanso

    Thank you for introducing me to the wonderful world of flexboxes! great tutorial!!

  68. Wow! I had bookmarked the article before and have come back to it today as a reference. Really like the re-haul, makes it even more useful! Cheers to you, Chris.

  69. Alan

    Great work on the updated format! The guide was crazy informative before but now it’s also a great cheat sheet when needed. Thanks!

  70. Ry

    Great guide, nice update! Has always been very useful.

    One thing I’ve noticed missing (here and almost every other flexbox guide) is how to do flex-grow and flex-shrink in IE10.



    Would be great to have this footnoted somewhere.

  71. I love all that can be done with the flex box model, now only if all the browser could support it the same way! How does the flexbos fall on browsers that don’t support the CSS3?

  72. Bob Prokop

    Thanks so much for updating this post — by far the easiest-to-understand guide to flexbox ever written. You deserve at least a six-pack of Rolling Rock for this one, Chris — if that’s still your brew of choice that is :-)

  73. stephen


    I was hoping someone might be able to help me out (I’m pretty new to all of the programming stuff).

    I created a flex box and arranhed the items in it in a column layout. I then did ‘justify-content:center’, but the elements stay on the left-hand-side of the screen, even though the width of the container is 100%. Is there an easy way to center everything in a container box when arranging elements as columns? Hope this makes sense.



    • Jay

      Hi Stephen, I believe that justify-content isn’t to be used for this purpose. If you flow the elements by column (vertically), the justify-content: center will really display the elements in the center bit of the flex box vertically, i,e, some space at the top, then your elements, then some space at the bottom. What you wanted is for each element to center align horizontally, which you can probably achieve by using text-align property.

  74. stephen

    Hi Jay,

    Thanks for getting back to me so quickly. Ah yes, I guess because I didn’t set a height on the flexbox, I didn’t see how the elements were centering vertically.



  75. Premkumar Alexis Jegannathan

    Thank you Chris, for the article. Crisp, crucial and highly valuable. I enjoyed it.

  76. Ethan

    Does Compass support flex box? I see that they have what seems to be the old version of flex box in the documentation. But then on, when you include compass you are able to use the other directives. Like @include display-flex? I’m unable to get this working locally however. Ideas?

    • Jozef Remen

      Forget about Compass and use Autoprefixer instead (with gulp/grunt). Personally, I just use it for vertical rhythm calculations now as Compass will be big no no for a libsass in C++.

  77. Srbiotik

    Hey i’m interested in why this background: darken(colour, % ) part of code is not working for me, i tried to do it by myself with my own examples and it didn’t work so i pasted your code form codepen and it still doesn’t work. I’m sorry if i’m asking a noob question and there is something obvious that i’ve missed!?
    Incase a haven’t been clear thats the example that concerns a making of dynamic navbar!
    Thanks a bunch!


  78. Srbiotik

    Oh, sorry i forgot i’m using the latest version of Firefox and Chrome!

  79. Srbiotik

    Thanks a bunch!

  80. Matt

    Bit of a long shot here, but do any Email clients support Flex box..? Would be useful in HTML emailers to rearrange the order of elements.

  81. Tilwin joy

    main axis – “The main axis of a flex container is the primary axis along which flex items are laid out. Beware, it is not necessarily horizontal; it depends on the justify-content property (see below).”

    flex-direction – “This establishes the main-axis,…”

    These two are in conflict right..? :)

  82. Yehuda
    Permalink to comment#

    Testing flexbox in Safari now.

    What works in all other browsers, either doesn’t work in Safari, or doesn’t work correctly.
    Really frustrating…

    The demos here don’t work correctly either (especially the last one).

  83. pankaj
    Permalink to comment#

    this property not working android 4.1.1 browser . How it will be work on mobile browser

  84. I think the Support Chart is out of date for Safari. Should read:

    6.1+ (new)
    3.1+ (old)

    According to

  85. Lance


    You have obviously given a lot of thought to how to present this information as clearly as possible.
    Outstanding work – thanks.

  86. Brian Hughes
    Permalink to comment#

    How do you all know what works in which browser version? Where is flexbox standing now for support?

    I just learned about flexbox yesterday so now I’m all anxious to learn more. I’m a little hesitant because of browser version support.

    • coolcat007
      Permalink to comment#

      You can find more detailed information about browser support when you type in “caniuse flexbox” in google.

  87. Stephen
    Permalink to comment#

    Hi, I was wondering if anyone could help me out with a flexbox problem. I’ve set a container width to 100% and put six div items with width of 20% in it. I was expecting to see five divs evenly space and the sixth div directly underneath the others, one line down (I’m using row-wrap). This kinda works, but there is a big gap between the five divs across the top of the page and the sixth div below them. I need to know how to get rid of the gap. Here is the Codepen:

    Any help would be much appreciated.



    • Yehuda
      Permalink to comment#

      try align-content: flex-start; on the container. I’m not too sure if it will help for your purpose, but with your demo it works.
      Also, I would rather set flex: 1 1 20%; on each sub item instead of specifying the width (again, it depends on what you want to do).

    • Saman
      Permalink to comment#
      div#container {
         align-content: flex-start;
  88. Stephen
    Permalink to comment#

    Hi there,

    Thanks for both of the tips; the first one works well and solves the problem I was having.

    If you have time, I was hoping you might be able to elaborate on the second one a little. In all honesty, I’m not really sure how the code is being interpreted. I understand that giving everything a flex size of 1 gives everything an equal amount of space, but is the 20% overriding everything the first 1? I’ve played around with the second 1 in the code you provided, but it doesn’t seem to do anything. Oh, and the purple box now fills the entire width of the screen, which looks good, but is it the first 1 doing that since it is clearly taking up more than 20% of the container now? Anyhow, don’t mean to be lazy; I can look this stuff up tomorrow. Time for bed in the UK though.

    Cheers again,


  89. NeedHate
    Permalink to comment#

    Guys, what about “order”. It doesnt look good in safari, even doesnt look anyhow. 8) how to make it work in safari?

  90. Yehuda
    Permalink to comment#

    I gave up on Safari. Not supporting it on my sites.
    You could just revert to floats for it, but when I discussed it with my employer he said “no one uses it anyways”.

    @Stephen, play around with flex: 1 1 20%

  91. Johnny
    Permalink to comment#

    Safari 5.7.1
    Works only this:
    display: -webkit-box;

    And that’s it. Nothing else can make work :-(
    I’ve read that this version of Safari is (old), but how it should to looks like?
    Can’t handle it…

  92. wilbur
    Permalink to comment#

    in the first example (with the 6 orange squares)… is there a way to request the current number of columns and rows within a flexbox container? or at least the current number of rows (since the columns are not rigid)?


  93. Paweł
    Permalink to comment#


    This guide is wonderful, seriously, guy who did this deserve a BIG nice glass of GOOD beer.

    But I have issue:
    I made a website, where container’s div is flex and direction is column.
    Inside this container I have 3 divs. I want last one (footer) to be always at the bottom of this page.
    Is this possible to do? I know it is of course ;) but I want to use only flex-box model.

    Regards, mates!

    • Paweł
      Permalink to comment#

      Ok, i got it, there was no question xD Sorry. Thanks anyway! This is best place to learn CSS Tricks.

      Regards again!

  94. NeedHate
    Permalink to comment#

    Paweł, use order: and width: parametrs.

    width: 100% and order: the last div in your list.

  95. Hasschi
    Permalink to comment#

    IOS7 use -webkit-justify-content
    justify-content doesnt work

  96. brimi
    Permalink to comment#

    one of the best explanation for css flexbox model

  97. Kaleb
    Permalink to comment#

    Great post man. I’ve been wanting to learn more about flexbox ever since one of the guys on my team showed it to me. This is the best resource I’ve found so far.

  98. Gopinath
    Permalink to comment#


    My requirement is need to alignment support all browser without use Javascript. Use only CSS/CSS3.

    Note: Particular para line Margin top value support all browser(Mozilla, Chrome, Safari) as per match PDF. But IE-11 browser some different its will came._ In case for adjust IE-11 Browser, at the time margin-top value change another browser._ So, how to modify all browser requirement. If any possible on that particular IE-11 alignment modification style-sheet.

    Please give any solution that issue.

  99. Permalink to comment#

    I am working with flexbox on a few different projects now and love it. Only downside is all the prefixes that you need.

    For my projects I made a less mixin stylesheet that has been tested and works in the most recent browsers (latest version -1).
    Hoping to help some more people out I put it on my github, so if you want a little help getting started you can grab it there

  100. rameeee
    Permalink to comment#

    ya its good.

  101. Permalink to comment#

    Best flexbox resource. I often use this page as a reference – many thanks!_

  102. Permalink to comment#

    I’ve been experimenting with flex-wrap recently, and found that Safari doesn’t support it (on desktop or mobile), although it claims to, ie. Modernizr.flexwrap is true. I’ve filed a bug report with Modernizr for this. Wanted to spread the word, since there seems to be some confusion around this property flying around in the wake of Firefox previously not having supported it.

    • Lester
      Permalink to comment#

      it seems many properties aren’t supported by safari:
      something as important and necessary as wrap makes it a no-go for me (but i’m a new-b)
      plus i think that, as great as it is [and CC knows how much i love him], combining old and new is still another hack that flex box was supposed to eliminate
      and i ain’t got time for that!

  103. Permalink to comment#

    This article is one of the ones I’ve read countless times right now. I’m near the state knowing it inside out ^_________^
    Great post! It’s a reference.

  104. Jarek
    Permalink to comment#

    I’m trying to build simple layout. Could anyone help me with this? I was wroten some code reading article.
    Want to have this:

    Try to open this (i want to display in this way)

    But now block number four is moved to center and on the bottom of block number two (whole layout). I want to get it on the right side of the block number two, but below of the block number three.
    (i must remove because message was rendering in wrong way)

    ul class=”flex-container”>
    li class=”flex-item1″>1 /li>
    li class=”flex-item2″>2 /li>
    li class=”flex-item3″>3 /li>
    li class=”flex-item4″>4 /li>

    .flex-container {
      padding: 0;
      margin: 0;
      list-style: none;
      width: 650px;
      display: -webkit-box;
      display: -moz-box;
      display: -ms-flexbox;
      display: -webkit-flex;
      display: flex;
      -webkit-flex-flow: row wrap;
      justify-content: space-around;
      align-items: stretch  ;
    .flex-item1 {
      background: tomato;
      line-height: 50px;
      width: 650px;
      height: 50px;
      margin-top: 0px;
      color: white;
      font-weight: bold;
      font-size: 0,50em;
      text-align: center;
    .flex-item2 {
      background: tomato;
      padding: 0px;
      width: 325px;
      height: 550px;
      margin-top: 0px;
      line-height: 150px;
      color: white;
      font-weight: bold;
      font-size: 0,50em;
      text-align: center;
      background: tomato;
      padding: 0px;
      width: 325px;
      height: 50px;
      margin-top: 0px;
      line-height: 50px;
      color: white;
      font-weight: bold;
      font-size: 0,50em;
      text-align: center;
    .flex-item4 {
      background: tomato;
      padding: 5px;
      width: 325px;
      height: 150px;
      margin-top: 0px;
      line-height: 150px;
      color: white;
      font-weight: bold;
      font-size: 0,50em;
      text-align: center;
  105. Carlos
    Permalink to comment#

    Thank for the writeup! I will implement it in a new project. :D

Leave a Comment

Posting Code

  • Use Markdown, and it will escape the code for you, like `<div class="cool">`.
  • Use triple-backticks for blocks of code.
      <h1>multi-line block of code</h1>
      <span>be cool yo.</span>
  • Otherwise, escape your code, like <code>&lt;div class="cool"&gt;</code>. Markdown is just easier though.

Current ye@r *

*May or may not contain any actual "CSS" or "Tricks".