A Complete Guide to Flexbox

The Flexbox Layout (Flexible Box) module (currently a W3C Last Call Working Draft) 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.

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)

display

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.

flex-direction

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.

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’>

justify-content

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.

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. Note that visually the spaces aren't equal, since all the items have equal space on both sides. The first item will have one unit of space against the container edge, but two units of space between the next item because that next item has its own spacing that applies.

space-evenly: items are distributed so that the spacing between any two items (and the space to the edges) is equal.

align-items

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

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 around each line

stretch (default): lines stretch to take up the remaining space

Properties for the Children(flex items)

order

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>; /* default is 0 */
}

flex-grow

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, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, the remaining space would take up twice as much space as the others (or it will try to, at least).

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

Negative numbers are invalid.

flex-shrink

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

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

Negative numbers are invalid.

flex-basis

This defines the default size of an element before the remaining space is distributed. It can be a length (e.g. 20%, 5rem, etc.) or a keyword. The auto keyword means "look at my width or height property" (which was temporarily done by the main-size keyword until deprecated). The content keyword means "size it based on the item's content" - this keyword isn't well supported yet, so it's hard to test and harder to know what its brethren max-content, min-content, and fit-content do.

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

If set to 0, the extra space around content isn't factored in. If set to auto, the extra space is distributed based on its flex-grow value. See this graphic.

flex

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.

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

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.

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:

Flexbox is certainly not without its bugs. The best collection of them I've seen is Philip Walton and Greg Whitworth's Flexbugs. It's an open source place to track all of them, so I think it's best to just link to that.

Comments

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? http://i.snag.gy/VHJsV.jpg thanks

@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?

The CSS Working Group has a document online of “…Mistakes in the Design of CSS”, one of them is this:

“Flexbox should have been less crazy about flex-basis vs width/height. Perhaps: if width/height is auto, use flex-basis; otherwise, stick with width/height as an inflexible size. (This also makes min/max width/height behavior fall out of the generic definition.)”

For your final example, how would you make the content (center row) take up all available space, so that at minimum, the footer is pinned to the bottom of the window – but if the content area has more content, the footer will push below, allowing scrolling. This can be accomplished by setting a min-height on the content row: calc(100% – header-height – footer-height) but it requires hard-coding or JS to accomplish AFAIK.

@Lawrence at the point of using flex does IE8 not become a problem already? I think the grid solution could be solved with nth-child. Then using media queries to make appropriate adjustments based on the users screen.

@Josh McCullough its pretty simple to achieve that, better and easier then ever before. Just use the flex property and set it to 1, for e.g:

.someClass {
flex: 1;
color: #ebebeb;
padding: 2rem;
}

flex is a very powerful property and can be used in the shorthand of flex: 1 1 auto; (grow, shrink and basis) – using just flex: 1 tells it to take all the remaining space thus making the footer stick at the bottom. Look an eye out for grid to make a proper entry into the browsers and we would be having magic on our plates in terms of layouts.

Well, it’s bad on many levels. Too verbose, hard to manage, it already creates “frameworks” around it, just to make it manageable. 25 years ago we already had tools, WYSIWIG IDE’s and ways to define UI and “responsive” views… For geeze sake, can we come back to roots and come up with simple and effective markup language with UI tools and plain resizing rules for view elements!?

Regarding the flex property:
Saying that the 2nd and 3rd parameters <flex-shrink> and <flex-basis> are optional is slightly misleading because it implies that <flex-grow> (the 1st parameter) is never optional. The truth is, <flex-grow> is optional as long as <flex-basis> is present (and obviously when the value is none). It’s only required when <flex-shrink> is present.

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.

Vendor prefixes aren’t just about syntax differences. They (arguably much more importantly) separate out implementation differences. What would happen if we just had one unprefixed word for a feature, and the syntax of its attributes was consistent across browsers, but the rendering behavior was different? Then you’d have to do ugly browser sniffing and serve different files to the client conditionally, like we did back in the dark ages of IE6.

Once everyone has a correct implementation, then the prefixes can be dropped. Otherwise, the most popular browser’s implementation of the feature becomes the de facto standard even if it’s the most broken (again, IE6)

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

For the items to wrap up onto the second line you can use the flex-wrap: wrap, then to align the items on the second line you can manipulate them with align-content.

Example:
flex-wrap: wrap;

align-content: (possible values)
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 around each line
stretch (default)

@Daniel
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.

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.

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.

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?

Something weird is going on in the first example’s pen (http://codepen.io/HugoGiraudel/pen/LklCv). 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.

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?

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?

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 bottomcolumn-reverse: same as row-reverse but top to bottom

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+: http://codepen.io/anon/pen/pEIKu

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.

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.

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?

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.

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}

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.

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.

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.

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:

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.

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…

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.

…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!

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!

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.

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

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.

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.

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 codepen.io, 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?

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!

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

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:

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

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.

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

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.

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.

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 github.com/annebosman/FlexboxLess

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.

it seems many properties aren’t supported by safari: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes
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!

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)

Inside this container, I have two items. A content area and a footer. Using “space-between” on the container sticks the footer to the bottom of the browser window and sticks the content area to the top of the browser window.

I want the footer to have a set height of 52px and I want the content region to automatically fill the rest of the empty space.

What CSS is needed for the content area to fill the remaining space relative to the footer?

I want to be able to infinitely expand the browser window and always have my content area fill the empty space and I never want the footer to change size.

Can someone point me to a tutorial or demo of using iframe within a flexbox container. I have tried and it is failing to keep aspect ration and the usual padding trick doesn’t seem to work. Alternatively is there an easy solution you could give me here.

It seems that example images for space-around in this article are a bit inaccurate. From these images, one may think that these values result in equal spaces between items, before first item and after last item. Actually, the space between items becomes twice as big as the space before first item/after last item, since the portion of free space per each item/line is distributed equally before and after it, so there are two halves of such portion between items, but only one half before the first/after the last one.

I kind of agree with the article. Both Flexbox and Grid layout have their pro’s and cons. The flexbox is more suitable for dynamic content (think about displaying a random amount of images of a random size), where the grid layout is preferable for known content areas. Both can adjust for the screensize, but are optimized for different applications.

The mobile-first 3-columns layout doesn’t work when adding a paragraph to the asides. I’ve noticed that any example, where flexbox is used for the entire layout, leaves out content inside these boxes. Doesn’t seem like flexbox is useful for layouts without a lot of hacking.

This is a pretty good quick guide. Just a couple things I noticed from a skim:

It’s not very clear how ‘order’ actually works. ‘order: 3’ doesn’t mean “put it at the third position”, it means “put it after any items with ‘order’ less than 3 and before any items with ‘order’ greater than 3”.
We (the Flexbox spec editors) strongly recommend not using the longhands of ‘flex’ unless you really, really want to cascade in flex settings from some other style rule, so I’d suggest somehow discouraging the use of ‘flex-grow/shrink/basis’ here (or, preferably, leaving it out/in an advanced section). The shorthand resets things in appropriate ways, and will therefore result in fewer cascading errors. Please use the shorthand!

Hi, I’m looking for the way to do a fullscreen menu for my website with flex, with a header on the top and the rest of the space with only 6 big responsive buttons. I’ve tried many things and I’ve check many websites. I would apreciate any help. Thanks in advance.

This is going to be an amazing feature right now. Unfortunately it still seems to be in it’s revolutionary infancy and I don’t think my employer would be happy if I tried to implement this on our sites.

So I was wandering, is there a good way of making the child elements of the flex grid not automatically span to the full width of the page. Only specifying widths every time is not very effective. No one should have to add a width: 1px; to every element within if they want it to behave properly.

Tons of love to Flexbox which just saved my weekend. I just had to redo an entire page which used to use an HTML table to present a matrix. After requirements changed, I realized I could no longer use a table since each “column” needed to have an arbitrary number of “rows”. In other words, I had to go from row-major format to column-major format. So I used Flexbox to lay out the columns in left-to-right (row) direction, and then lay out each child in each row in top-to-bottom (column) direction. But then I needed to reorder each row in reverse order, which Flexbox also made easy: use either the “order” property or set the direction to “column-reverse”. Done. Voila. The JS that I wrote to make it happen is now half the size, and the CSS is turning out to be smaller, too. Woo-hoo!!!!!

Your first example at this link (http://codepen.io/HugoGiraudel/pen/LklCv) does not work in IE 11. IE doesn’t seem to like -webkit-flex-flow. Adding flex-wrap:wrap; flex-direction: row; or just flex-flow: row wrap; works though.

hey guys, need help here. I write css for the screens 1440 resolution. Got a container and 3 columns in it. Used this tutorial and it worked great in FF and Chrome, but in Opera it does not. Col 1 and 2 are fully apart and the 3rd column is under the 1st. Just to mention I am new here (i mean webdesign). Here is the code:
@media screen and (max-width: 1440px) {

It’s great that you have given the html, css and result, but I used yours exactly and it is fine on my laptop, but on my Android phone the header, main, aside1, aside2 and footer are all on the same line (both portrait and landscape). I find a difference between resizing my laptop monitor and actually viewing it on other devices.

I’ve been working on this layout which I managed to work perfectly in modern Firefox & IE browsers, but it’s not working as expected in chrome and safari (which leads me to believe I’m not implementing the flex box correctly).

Any advice would be greatly appreciated….I’ve tried all manner of logic including flex box within a flex box to make this work….perhaps it’s a limitation of the way flex box is being implemented in webkit browsers or vice versa.

I noticed when declaring flex property for parent that hold some elements (for example ul is flex, li are flex items (they are inline or inline-block)), when I set to some list item margin-right:auto, it push all other elements to the edge of the parent container?

Thanks, as always, for a very informative post. It really fast-tracked my understanding of using the flexbox model.

One of the hardest things to wrap my head around was the flex-grow, flex-shrink and flex-basis properties. Not so much the concept of what they were, but how the actual values played out.

My basic assumption at first was that if I set the flex-basis to a static size, say 200px, and flex-grow of Item X to “2” and the other items in this container to “1”, that the width of Item X would be exactly 2 times the width of any of the others. This was not the case. It was always greater than 2 times.

After looking a little closer at the numbers it was applying, the first thing I noticed was that the flex-grow/flex-shrink is a ratio of these values amongst all children in that flexbox for that specific property. The grow and shrink values have nothing to do with each other.

As in the example given above, the ratio would be 2:1 for Item X’s width to the flex-basis value. But the piece that was eluding me, and causing the actual width values to not follow this ratio, is that the ratio is based on the amount that the containers have grown past the basis width (or under the base width for flex-shrink.)

That being said, the key is that if you subtract the basis width from each item width, then the remaining width will follow the ratio.

Now, if you are not setting the flex-basis property manually, then the default will be “0%” and the ratio is closer to being what you would think, but there is still a minimum width on these elements that is factored into the ratio calculation as described above.

Hopefully, because flexbox is being used, the ratio won’t need to be exactly correct and the layout will still look and work great. That’s the whole point of flexbox, right?

I just wanted to share this extra information with those who like to understand where the numbers are coming from when it doesn’t come out as you may have thought at first.

Warning! Description of justify-content / align-items is incorrect. Behavior of the last two changes depending of flex-direction. Article says it should be independent. “This defines the alignment along the main axis.” No! If flex-direction = column, that will align items along the cross axis. To align items along main axis you’ll need to change align-items instead.

Here, “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.”
The navigation don’t works in Chome 41.0.2272.101 m

Questions:
* Should we avoid using “flex-basis:auto” for the time being? And if so, should there be a note accompanying that image?
* Am I right in thinking that the w3 spec is a bit confusing/disorganized in those places? Worthy of me sending a comment/email to somebody?

Originally ‘auto’ meant ‘content’ or natural size. Now auto means look at the height/width property and a new value of ‘content’ has been added. Chrome is still treating ‘auto’ like ‘content’. Firefox and IE are not.

So ‘auto’ is only useful if you have a height or width set, which is pretty useless because you could just use that value as the ‘flex-basis’.

These css are like readymade ui-bootstrap components or angular itself. They work off-the-shelf. Web-pages development are becoming breezy now, given most of the common burden is taken by the framework. Love it, thanks!

I think align-items and justify-content got mixed up in the example shared. Also, you the container article is missing a height, which ends up in confusing the result of applying align-items and justify-content as the same in that special case.

Another great article!
Using this page as a guide and reference, I created a web-app based log in template that looks like a phone-app. It’s mostly just an exercise in column layout for flex; it helped me gain a much greater understanding of flex properties and I thought someone else might care to poke at it to help learn.
Here’s the result: https://jsfiddle.net/Serk0413/y6ugdxgx/10/embedded/result/ (complete w/ “hamburger” nav)
Here’s the fiddle (sorry, no pen): https://jsfiddle.net/Serk0413/y6ugdxgx/
It uses a full mix of css flex props including a flex column w/ nested rows and nested traditional css (no floats!)

I really like the concept of flexbox, but with needing to support IE9, looking for a way to do that with a graceful fallback. Do you have any suggestions for a graceful fallback or is it better to just style it “traditionally” for .no-flexbox (using Modernizr)?

Total noob when it comes to flexbox, but I was wondering something. Is it possible to have, in a list comprised of multiple rows, the first row “space-around,” and the other rows after left align? In my list of items I’m not really a fan of if one or two items are wrapped to the next row, they “space-around” and end up in the middle, it kind of makes you lose track if you are going down the list (make sense?). It’s no biggie, just was wondering if there was a way to specify the last row or something. Great tutorial btw! Thanks in advance.

When using the flex-shorthand in Safari 7 (7.1.6) (-webkit-flex) without specifying the third parameter (-webkit-flex-basis), Safari will compute the value 0px and wrapping via -webkit-flex-wrap is not going to work. In order for Safari to wrap via flexbox -webkit-flex-basis must be auto (which is Safaris default value). So, if you use the shorthand and don’t want an initial size for your flex-item, set the third (or the second parameter if you leave out shrink) to ‘auto’ (f. e. -webkit-flex: 1 auto; or -webkit-flex: 1 0 auto;).

@Alex: maybe a bit late, but this is my solution and it works pretty well.
Create a number of extra blocks, the same size as your other blocks but with height=0, to fill up at least 1 line of your screen (or any screen). Because height=0 you will not see them, but they still take up space in the x-direction. Since you could fill up 1 full line you don’t see the odd alignment on the last line even when it is there. The alignment you see is on the last but one line. See the solution on https://jsfiddle.net/h0Lww6mk/3/

It’s worth noting is that Internet Explorer struggles when you used mixed units. I often use flexbox with margins and calc, so I might use something like:

.menu-item {
width: calc((100% – 20px) / 3);
}

This works fine with Safari, Firefox and Chrome, but not Internet Explorer. I guess it’s a rounding error, and it won’t affect all resolutions, but a combination of screen width and element width might sometimes mean you only get two columns on a line instead of three. To get around this, I use:

Thank you for the tutorial. I followed it whilst updating something I did for a friend’s project before, but have come into difficulties. The three elements (the twitter widget’s container, the cbox’s container and the ccentre’s content) I was trying to update to use flex like in the tutorial, but it’s not worked. It looks like the ccentre might be the cause. Any ideas? Here it is on Codepen: http://codepen.io/seasalt/pen/GppzmG

Hello. I have stumbled upon this interesting StackOverflow question re justify-content: flex-start and margin: auto on a container. I don’t know the answer and I wonder if there is any solution to this.

Thanks so much for the article! I learned a ton. One question though, the note that you included in the background section “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. ” links to an article that is over a year old and has a note on it saying that it is in-flux. Are there any updates to that article coming down the pipeline? I would love to read the two in tandem and better be able to grasp in which situations each would be most appropriate.

Try adding a background color to the .navigation a and you will see that they are not the same. Using inline-block keeps you dependent on the browser default use of extra space left and right of inline li elements. This rendering can be fixed by floating the li elements, but flexbox is a nicer (modern) way of achieving that effect.

The proposed changes to CSS were initiated years ago, along with the introduction of HTML5. Most of it are in fact additions to CSS and HTML, rather than changes. The reason was that certain page layouts that you see nowadays, were very difficult to implement with the old specification. Therefore these new tags were added to simplify web structure/layout, rather than to complicate it.

Take for instance flexbox. Before it was very hard to make a dynamically scaling website. Using just percentages to scale the sections just didn’t cut it. One improvement was the introduction of the calc() function that could use percentages and static units together, but even with that it was still hard to read code. Flexbox was a great addition that is very easy to use once you read this article.

And as a matter of fact, you are still free to use CSS2 and HTML4 if you wish. Nobody is stopping you, but you deny yourself some awesome tools if you do

The reason that I enjoy working with the web is that it’s always growing. There’s always something more to learn.

The same is true for any technology or even life in general, really. Without new features and new capabilities, we atrophy and fail to realize our full potential.

I suspect that relatively few people want to settle for what we have now and just work with that.

The W3C isn’t a single person who has neglected you, or any of us. It’s an organization, and a democracy, guided by the people and companies that invented the web and continue to use to everyone’s benefit.

It should probably be noted that the W3C documents recommendations, not requirements. Everything’s optional.

Both of those articles, and more linked to at the end of Bruce Lawson’s article, were written by people much smarter than me.

I hat to say it, but the frustration expressed by PPK and many others strikes me as very similar to my daughter’s frustration with going to school. After all, she already has TV, YouTube, and all the toys she needs at home :)

I want to put a link on images wich are in a contener flexbox. before putting the link, flexbox work, but after putting the link, it doesn’t. WHY? I suppose it’s a problem with my html? Can somebody can give me an exemple about how to do?
thank you so much!

Hi , I need to align all elements inside flex container to each other. Suppose I have made two div of equal height using flex and now I want to make the all the elements inside the div to align to each each other. Is that possible?

This is an excellent guide and I pretty much learned how to layout a page in about an hour using this. I cannot wait to test it out more and see how it all works in different scenarios. Thank you Chris & Team!

I am trying to replace a grid layout where I used display: table and table-cell to align content vertically with flexbox.
My problem with flexbox is, that I can not get a second child item to align vertically. You can see this in action here: http://codepen.io/anon/pen/BjXbrw
No matter what I try, I will either lose vertical centering of the heading or the second child won’t align. What am I doing wrong here?
Thanks!

Sometimes I smile when reading these articles (and this one is just fine BTW) but I remember back to the dark ages when one could code a fairly decent web page on a single sheet of paper whereas now, it takes endless articles to even understand the coding and then one ends up with megabytes of code … and it’s still just one page but a lot “prettier” (and requires up to 1000X the bandwidth and server storage LOL). And we call it progress.

Regarding the flex property:
Saying that the 2nd and 3rd parameters <flex-shrink> and <flex-basis> are optional is slightly misleading because it implies that <flex-grow> (the 1st parameter) is never optional. The truth is, <flex-grow> is optional as long as <flex-basis> is present (and obviously when the value is none). It’s only required when <flex-shrink> is present.

This is an awesome post. It has helped me several times.
I am having one issue that I cannot figure out. I can’t get a single line of text to vertically center within an element. It seems so simple, and yet I’ve wasted hours without any luck.
Would anyone be willing to comment on this Codepen? Resize the width below 900px and you’ll see what happens.

This article has been my “cheat sheet” for flex-box standard.
I have encountered a bug on firefox that does not allow elements to be flex containers.
It took me AGES to find that out, so I wanna share this with other folks that might be going though the pain I have just experienced!

Permalink to comment# JULY 17, 2014
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? http://i.snag.gy/VHJsV.jpg thanks

I’m not clear on whether I would still need prefixing on any flex code as of this writing in August 2016. If the answer is “depends on what browser support you need”, I really wouldn’t know or couldn’t predict exactly who might visit my commercial site.

Should prefix code be inserted as a safeguard, OR is it deleterious to add vendor flex prefix code if said vendor has provided full flex compliance in more recent browser versions?

Bottom line: is it just a good idea to add vendor prefixing for flex at this stage of the game and is there any possible downside for doing it now (8/2016)?

You can get some useful insights (and ones very specific to your site and users) by installing Google Analytics. With the statistics it gives you, you can see the browser breakdown of the people who come to your site. I think that would let you know how much of a need there really is for support for given browser versions.

I just want to say thank you. As I’ve been getting up to speed with css over the past year or so, I have referenced this page a thousand times. It has been just so helpful. I had to write and give you a well-earned “thank you”. Great work. Much appreciated. Thank you.

Hi.
Great stuff in here, but I am obviously missing some basics from my end. If somebody can explain. I am about to achieve from a last example (full page with all these elements .header, .main, .nav, .aside, .footer ) following result. .ASIDE2 – purple part to be bellow .MAIN – blue part. And ASIDE 1 – yellow to be still running next to them. In short – add PURPLE under BLUE and extend YELLOW.
Thank you,
Igor

Nice one, I have a question tho, with this new knowledge I wanted to try my skills on some kind of framework. I uploaded everything to “http://tesserakt.pro/demo/repsonse”. But why do the two col-1 at the top not have the same width as the col-2? They should add up and make 50% width? right? They don’t I guess it has something to do with the flex-shrink and flex-grow but I’m not sure.

I suppose If you consider that all your visitors will have a recent browser, you can use only flexbox. If some of them still use ie6 and you have to enable them to use your website, you have to propose another way to display…

Edit suggestion: In the flex-direction section, the visual examples do not match the order shown in the css code snippet. I thought for some reason flex-box treated “up-and-down” as a “row” , and “left-to-right” as a “column” from this.

Since all the other sections match in order from what the visual example is with the code snippets, I was confused for a bit.

Sorry about missing html in my comment above. Here it is: http://codepen.io/localnepal/pen/vyXPmy
So, the image dimensions in box1 change in the display as I enter new text in box3, even though it’s not more text than was there previously.

Seems flex wrap could be a bit more flexible, if it support indentation and hanging indentation, as for paragraphs.

Use case: a bunch of thumbnails with dates underneath, one flexbox filled for each month, say. When scrolling quickly, it would be nice to see the new months at the left margin, and “continuation” lines indented. I’ve been doing this with floats and weird margins, but don’t see how to convert it to flexbox.

Hi, great tutorial.
Is it possible to use flex to make a perfect grid with some square boxes of side double than other square boxes. The grid is supposed to contain only two kind of boxes-small and big(with side double to that of small box).

I´m from Germany and thats why my English isn´t very good.
So please try to anwer in easy words :)
I have taken the code from the Flexbox at the beginning of the website.
But now I´ve recognized that aside 1 and aside 2 aren´t next to the main part.
I´ve tried to put in codes which are already written in the comments, but it doesn´t work.
So could someone please give me a code I am able to paste in my code?
As far as now the code is:

@Christian
Hi, I am not a code pro, but even I could see, that your code is like scrambled eggs. You shouldn’t copy/paste code into your code, when you don’t know were and what. I think you should start a new with a clean HTML and keep it much simpler.

We typically read digital content vertically so it doesn’t make sense to me why row would have higher priority over column.

Even React Native has flexDirection set to ‘row’ by default so I’m not the only one who thinks column should be the default value of flex-direction.

This makes styling web and RN problematic because in order to have the same developer experience, you either have to set the flex-drection of divs to ‘column’, or set the flexDirections of Views to ‘row’.

This is the best Flexbox tutorial I’ve read. Thank you for the great work. The figures really make things much easier. It would be even better if there is a real webpage example built with Flexbox, like a more complete version than the last example, so that we can see how Flexbox is used in real life.

In the last example, what if we want to set the height on the wrapper? If done, the header/footer and the content seem to take up the height evenly. Is there a way we can limit header/footer to take certain height, and have the middle content take the rest?

Thanks for all of the great information, it really helped me to understand flexbox. Whilst I was learning, I put together an open source flexbox grid that uses a traditional 12 column approach, which I find helps to apply flexbox’s attributes easier. It’s called Eixample, and you can check it out at: https://github.com/mobilejazz/Eixample

@Alex and @AndyMaleh (Three years later and based only on the picture Alex showed us) Yeah you can do a “Perfect” (why perfect though?) product grid with only flex, you just need to justify your content to flex-start and be careful with your margins… also you will need to apply margin to the title too (please look at alex’ picture, it’s clear that margin is applied to everything there).

Very interesting article. I have a few questions I’d really appreciate if you could answer. I’ve been out of front end development for a few years exploring culinary arts but decided to get back into design and front end dev.

So I’ve pretty much only dabbled in responsive design when it was rather new. So right now I am trying to figure out where to get started and what technologies are safe to use. Can I trust pretty much full browser support for flexbox’s “new” syntax without worrying about all the fallbacks?

And what about CSS grid, safe for production with fallbacks? That being said, why would I even bother creating the layout twice and bloat my code if fallbacks for layout are required?

Thanks so much for your time. Just a few tips and tricks ;) would be great!

Hello. GREAT STUFF!
Been using this website for a while, always coming back when i need a refresher.
My questions is: Using display flex on a element while having the element styled to have FIRST-LETTER colored, WHICH it is at mobile screen cause im only calling the display at medium-up. So at those larger sizes, although the first-letter styles are still applied, the flex box gets rid of the styles. Why is this so?
Thank you!

Hi Michel,
The Flexbox spec forbids :first-letter from applying within flex containers, see the “Flex Containers” section. This is because :first-letter and :first-line are very tricky to implement, and there didn’t seem to be a strong enough reason to make them work.

You should be able to apply :first-letter directly to a flex item that’s display: block, though.

If that’s not good enough, file an issue against the CSSWG with an explanation of what you’re trying to do and why this needs to work; the restriction can be lifted if there’s a good reason for it to work. (That said, implementation of :first-letter and :first-line is rather painful in the layout engines, so even if the restriction is lifted in the spec, it might be awhile before anyone is willing to implement it.)

Hi! i’m SeonghoonBaek, i’m frontend developer in Korea :)
Can i post this article in my blog? i wanna translate in Korean this article because this article would help many frontend developers in Korea :) and my colleagues

Wow. Just started to look at using flexbox as I update some educational materials I began 22 years ago (yes html2!) from html 4 to html 5. Been overwhelmed at the change from frames to div. But your site puts things in the language a non-programmer teacher can use to update to something other than frames. Thanks for such a well done site. Now lets get my hands dirty and brain overloaded. My main frame page is 11 frames.

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.