Introduction
Flexbox is a new layout mode in CSS3 that is designed for the more sophisticated needs of the modern web. This article will describe the newly-stablized Flexbox syntax in technical detail. Browser support is going to grow quickly, so you’ll be ahead of the game when support is wide enough for Flexbox to be practical. Read on if you want to know what it does and how it works!
Why is Flexbox needed?
Authors have long been using tables, floats, inline-blocks, and other CSS properties to lay out their site content. However, none of these tools were designed for the complex webpages and webapps we are making nowadays. Simple things like vertical centering require work. Complex things like flexible grid layouts are so hard that it’s considered ambitious to roll your own, hence the success of CSS grid frameworks. Still, if so many projects needs to do these things, why can’t it just be easy? Flexbox aims to change all that.
Specification Status and Browser Support
The Flexbox specification has been a work in progress for over 3 years. Various browsers have implemented different versions experimentally. In September 2012, the 3rd major revision of the Flexbox syntax reached the W3C Candidate Recommendation stage. This means that the W3C is satisfied with the current syntax and is encouraging browser vendors to implement it.
Flexbox Specification Timeline:
- July 2009 Working Draft (display: box;)
- March 2011 Working Draft (display: flexbox;)
- November 2011 Working Draft (display: flexbox;)
- March 2012 Working Draft (display: flexbox;)
- June 2012 Working Draft (display: flex;)
- September 2012 Candidate Recommendation (display: flex;)
Browsers are adopting Flexbox quickly. Chrome 22+, Opera 12.1+, and Opera Mobile 12.1+ already support Flexbox as described in this article. Firefox 18 and Blackberry 10 will follow soon. I recommend reading this article in a supported browser to see working examples.
Concepts and Terminology
Though Flexbox makes it trivial to create layouts that would have been difficult or impossible in the past, it takes some time to get used to the Flexbox way of doing things. New terminology and new abstractions can be a barrier to using Flexbox, so let’s discuss them up-front.
Flexbox consists of Flex Containers and Flex Items. A Flex Container is declared by setting the display property of an element to either flex
or inline-flex
. With flex
the container is a rendered as a block. With inline-flex
the container is rendered inline.
Here is an example declaring a Flex Container.
gistfile1.css
.flex-container {
display: -webkit-flex;
display: flex;
}
This article will show all appropriate vendor prefixes in all examples.
Every child of a Flex Container is a Flex Item. There can be any number of Flex Items. Everything outside a Flex Container and inside a Flex Item is rendered as usual. In short, Flexbox defines how Flex Items are laid out inside of Flex Containers.
Flex Lines
Flex Items are positioned inside a Flex Container along a Flex Line. By default there is only one Flex Line per Flex Container.
Here is a simple example that shows two items as they are positioned by default: along a horizontal flex line, from left to right.
Writing Modes
An important part of customizing your Flexbox is changing the direction of the flex line. By default, the Flex Line goes in the direction of text: left to right, top to bottom.
There is a W3C Working Draft for a new feature called Writing Modes. Writing Modes are a new way to write text right-to-left, or even vertically, as you might in certain languages.
Writing Modes are a work-in-progress, but Chrome currently supports the direction
CSS property. If we set the direction in the previous example to rtl
(right-to-left) then not only is the text drawn right to left, but also the Flex Line changes direction, changing the page layout.
This might clarify why a lot of the Flexbox terminology is so abstract. You can’t just say “right” “left” “up” and “down” when you’re making no assumptions about the language of the page.
The Main Axis and the Cross Axis
To abstract over the writing-mode, Flexbox uses the concepts of the Main Axis and the Cross Axis. Flex Lines follow the Main Axis. The Cross Axis is perpendicular to the Main Axis.
The names for the starting points, ending points, and directions of each axis are as follows:
- Main Start
- Main End
- Main Direction (sometimes called the Flow Direction)
- Cross Start
- Cross End
- Cross Direction
It is crucial to understand the Main and Cross terminology before continuing. Everything in Flexbox is relative to these axes. In all of our examples the writing-mode will be left-to-right, top-to-bottom, but you must keep in mind that this will not always be the case.
Properties of the Flex Container
flex-direction
The flex-direction
allows you to change the axes of the Flex Container. The default value of flex-direction
is row
. With this value, Flex Items are laid out in the direction of the writing-mode
. Again, that means left-to-right, top-to-bottom by default. The other values are as follows:
- row-reverse: The Main Start and Main End are swapped. If the writing-mode is left to right, Flex Items are now laid out right to left.
- column: The Main Axis and the Cross Axis are swapped. If the writing system is horizontal, the Flex Items are now laid out vertically.
- column-reverse: Same as column, but reversed.
Let’s take our previous example and change the flex-direction
to column
.
Now our Flex Items are being laid out vertically.
justify-content
The justify-content
property of Flex Containers adjusts the positions of Flex Items on the Main Axis. The possible values are:
- flex-start (default)
- flex-end
- center
- space-between
- space-around
Here we set justify-content
to center
to cause Flex Items to be centered on the Main Axis:
flex-start
, flex-end
, and center
are straightforward. space-between
and space-around
distribute the whitespace between Flex Items in more subtle ways. This diagram from the specification explains it best:
align-items
align-items
is complementary to justify-content
. align-items
adjusts the way Flex Items are positioned on the Cross Axis. The possible values are:
- flex-start (default)
- flex-end
- center
- baseline
- stretch
Here we set align-items
to center
to cause Flex Items to be centered on the Cross Axis:
Again, the flex-start
, flex-end
, and center
values are straightforward. stretch
is also fairly simple: it causes Flex Items to be stretched out from the Cross Start to the Cross End. baseline
causes Flex Items to be aligned along their baseline. Baselines are calculated based on the content of the Flex Items. This is best explained by the following image from the Flexbox specification:
flex-wrap
Up until now, every Flex Container has had only one Flex Line. Using flex-wrap
you can create Flex Containers with multiple Flex Lines. The possible values for flex-wrap are:
- nowrap (default)
- wrap
- wrap-reverse
If flex-wrap
is set to wrap
, Flex Items wrap onto additional Flex Lines if there is not enough room for them on one Flex Line. Additional Flex Lines are added in the direction of the Cross Axis.
Here is an example using flex-wrap
:
wrap-reverse
is the same as wrap except new Flex Lines will be added in the opposite direction on the Cross Axis.
align-content
align-content
modifies the behavior of flex-wrap
. It is similar to align-items
, but instead of aligning Flex Items, it aligns Flex Lines. As you might expect, its possible values are similar:
- stretch (default)
- flex-start
- flex-end
- center
- space-between
- space-around
These values are analagous to their counterparts in justify-content
and align-items
.
In this example we set align-content
to center
:
flex-flow
flex-flow
is a shorthand for flex-direction
and flex-wrap
.
flex-flow: [flex-direction] [flex-wrap]
For example:
gistfile1.css
.flex-container {
-webkit-flex-flow: column nowrap;
flex-flow: column nowrap;
}
Properties of Flex Items
A Flex Item is any direct child of a Flex Container. Text in a Flex Container also gets treated as a Flex Item.
The contents of Flex Items render as normal. For example, while setting float on a Flex Item does nothing, you could have a floated element inside of a Flex Item.
Flex Items are said to have a Main Size and a Cross Size. The Main Size is the size of the Flex Item in the dimention of the Main Axis. The Cross Size is the size of the Flex Item in the dimention of the Cross Axis. Effectively, the width or height of a Flex Item may be its Main Size or Cross Size depending on the Flex Container’s axes.
The following properties adjust the behavior of Flex Items.
order
order
is the simplest one. Setting orders for Flex Items adjusts their order when rendered. In this example, we set the order
of one Flex Item to -1, causing it to be displayed before any other Flex Items.
This can be useful for accessibility, where the document order and the displayed order may need to be different.
margin
You may be familiar with the normal effect of margin: auto;
. In Flexbox it does the same sort of thing, but it’s even more powerful. An “auto” margin will absorb extra space. It can be used to push Flex Items into different positions.
Here we declare margin-right: auto;
on the first Flex Item, causing all the extra space to be absorbed to the right of that element:
Here we use margin: auto;
to achieve the holy grail of CSS layout: true vertical centering:
align-self
The align-self
property of Flex Items effectively overrides the Flex Container’s align-items
property for that item. It has the same possible values as align-items
:
- stretch (default)
- flex-start
- flex-end
- center
- baseline
In this example we give different align-self
values to each Flex Item:
I included two baseline Flex Items because their alignment is only relative to one another.
flex
Now we’re finally going to put the flex in Flexbox. flex
specifies how a Flex Item will be prioritized when free space is being distributed on the Main Axis.
Let’s look at each of the common values one at a time.
flex: [number]
This syntax specifies a number that represents the ratio of free space that should be taken by this Flex Item.
In this example, the first Flex Item consumes 2/4 of the free space, and the other two Flex Items consume 1/4 of the free space each:
It can be useful to set the number to 1 for every Flex Item, causing free space to be distributed evenly:
flex: initial
A Flex Item with its flex
value set to initial
will be inflexible when there is free space, but can shrink smaller if needed.
flex: auto
A Flex Item with its flex
value set to auto
will be fully flexible along the Main Axis.
auto
currently works in Opera 12.11 but does not work in Chrome 23.0.1271.95. You can often work around this by using flex: 1;
.
flex: none
A Flex Item with its flex
value set to none
will be fully inflexible in all situations.
advanced flex
flex
can also be used as a shorthand for specifying flex-grow
, flex-shrink
, and flex-basis
in one declaration:
flex: [flex-grow] [flex-shrink] [flex-basis]
Most use-cases do not require this syntax. Further, it requires a more specialized understanding of the flex algorithm. If you’re feeling brave, take a look at the specification.
You can also specify each of flex-grow
, flex-shrink
, and flex-basis
as separate properties. I strongly recommend against this: when using the flex
shorthand, more sensible defaults are applied to the values that are not given.
visibility
When it is implemented, visibility: collapse;
will be distinct from visibility: hidden;
and display: none;
for Flex Items. With collapse
, the element will affect the Cross Size of the Flex Container, but it will not be displayed nor will it consume any space on the Main Axis. This will be useful for dynamically adding and removing Flex Items without affecting the Flex Container’s Cross Size.
Currently, visibility: collapse;
does not appear to be correctly implemented in any browser. visibility: collapse;
appears to do the same thing as visibility: hidden;
in current implementations. I expect this to change soon.
You can see a good mocked-up example of how collapse
will work in the spec.
Conclusion
As you can see, Flexbox is a powerful new layout mode that will revolutionize layout for websites. As you can also see, it requires a whole new way of thinking. Hopefully this article has prepared you to start making websites with Flexbox. I don’t know about you, but it seems to me that the future is awesome.
Comments
We moved off of Disqus for data privacy and consent concerns, and are currently searching for a new commenting tool.
That said, i made a fun one that also concatenates its text-content:http://jsfiddle.net/ronadam…
Yeah, this looks very promising.
Thank you thank you thank you for writing this comprehensive reference on flexbox. I am sure I will be coming back to this for years to come.
I had been using https://developer.mozilla.o… as a reference for a while, but its fairly outdated.
Supporting older browsers that used the -*-box or -*-flexbox are fun</sarcasm>, especially since they don’t recognize the max-width or height properties correctly. Yay experimental features.
Looking forward to being able to really use flexbox. For the browsers that support it, calc() allows the construction of some simpler flexible layouts:
https://developer.mozilla.o…
It requires more knowledge of the fixed sizes in use by other elements, so not as nice as flexbox, but it works well enough if you just want a fixed size top header, bottom footer and an area in the middle that takes up the rest of the space.
truly very good article. well done!
I recently had to rip flexbox out of a prototype I was working on, replacing the functionality with JavaScript based flexing. Not fun. Flexbox is definitely the way to go if you’re able to count on browser support.
I think it should be noted that flex-wrap doesn’t seem to work in Firefox (I’m running Nightly – v20). Sadly, from the docs it appears that they don’t support multi-line flex. https://developer.mozilla.o…
Open up about:config and set layout.css.flexbox.enabled to true.
This is great and promising!
I just hope it will not become outdated in a while.. This is what happen to the old flexible box model.
Be aware that it’s dangerous to use something unstable – you never know if it will not disappear.
Yeah, flexbox has definitely changed a lot over the years. The news that this version reached Candidate Recommendation status is very very promising though.
Great article. It would be nice if the IE version of Flexbox was included too, with the -ms- prefix. The syntax changed after IE10 implemented Flexbox, so they are stuck in some inbetween state. I feel that pain as the same happened to me when I was writing the flexbox part of Smashing Book 3. It looked like it was going to be the final syntax, then wasn’t.
You can see the IE syntax at http://www.w3.org/TR/2012/W… or http://msdn.microsoft.com/e…
I didn’t want to cover any of the older syntaxes: there are lot of articles for these, and not enough for the current Recommendation Candidate syntax. I’m guessing IE11 will support the new syntax, which would be awesome!
There seems to be very little covering the MS syntax as it existed for such a short period. I do worry that developers will forget to include the IE version, but it makes sense to keep the tutorials concise. I\u2019d be surprised if they don\u2019t update to the final syntax, sans-prefix in the next version, yeah.
Great article that really helps you to understand the new terminology.
I would like to see a full mocked up demo in the future if possible!
Keep up the great work guys
Great overview! I can’t wait until we can really start using this broadly in the wild.
Am I right in seeing the iOS6 does *not* support this? caniuse.com suggested it was supported w/ the prefixes, but i tested the demos here on an iOS6 device and it did not work.
iOS6 supports an older version of the Flexbox syntax that is not discussed in this article. The dark green \”Partial support\” in caniuse refers to this.
Do you have an article on best practices for this? I am trying to find a good mix to support iOS5.1x+ and latest browsers without mudding the CSS
I personally wouldn’t try to use Flexbox on iOS yet, I’d stick to traditional techniques until support improves.
It should be good to notice FF users at the beginning of the article that the examples won’t work for them.
Excellent article though!
I prefer articles not to state things like that, since Firefox will eventually support it. The article will then be wrong.
Firefox 18 now supports flexbox with the -moz- prefix, even if it must be activated in about:config it would be very nice if your jsFiddles worked not only in webkit.
cool! works in chrome but not in rockmelt.
A pretty detailed article. Thanks!
I hope the browsers start fully implementing flexbox. For me this is the most important part of the html5 spec, way more important than box-shadow, transforms or animations but it seems as the least supported feature. Even if the spec changed about a year ago, you\u2019d say people are pretty tired of floating and clearing all their content or constrain themselves to grid frameworks.
This is not part of the HTML5 spec. It’s a separate standard.
These examples don’t work in safari either.. 🙁
Didn’t read it all the way, but I can confidently say that this will be a very useful css rule in the future. It surely beats display: table-cell; … I had an issue trying to vertically align a block 1 morning ago and had to resort to the margin css property.
Any polyfills for the new flexbox? Maybe something using a fallback to the old syntax?
Just wanted to point out that in order to vertically align content to center (align-content: center;), you MUST set the container to wrap (flex-wrap: wrap;). It would be nice if the article stressed this.
If anyone’s wondering, Firefox Nightly supports this now.
Wonderful, but not for comercial use yet unfortunately.
typo in \”newly-stablized\”.
Btw, I find the text more readable when I turn off `text-shadow`. That white shadow is too bright and noisy, and makes the text less clear.
Just noticed the post below on coming here to post that FF doesn’t seem to be working with flexbox. Despite what it shows in the spec at Mozilla developer network, flexbox is not working in FF 18.02, with or without -moz- prefixing.
These are good tips..I like the sand advertising..^^..it\u2019s fresh and original..^^
, I find your article engaging and refreshing.
Thank you.
Thanks for giving me the useful information. I think I need it. Thank you
Powerful, but complicated. At least for my simple mind…
Incredible post. Thank’s for taking the time to write this.
Hi guys,
Really thanks for the article ! I have played a bit with flexbox and I already love it!!! but I have a question for you experts 😉
http://jsfiddle.net/BenNG/Q…
I wanted to know how is it possible to put (test1, test2, test3, …) in the middle of the box with the exact the same configuration. (I mean the has to take all the place in the box with the border blue 🙂 )
Thank you !!
Superb article! Helped a lot
Implementing it in the mobile version of:
http://www.eattopia.com
Shouldn’t the default for align-items be \”stretch\” instead of \”flex-start\”? I’m a little confused.
This is typical. What a mess.. how about real code and you show how that it works!.. you wont because it wont work, doesn’t matter which browser. You spend all this time explaining and instead you should give real examples to solve real problems which you then demonstrate with examples so people can just copy and paste the code into a webpage and have it work. Nobody doing flexbox does that, I wonder why LMAO
I have just started learning about Flexbox. Is this layout model still the way to go, since this post? Also, how does it tie into responsive web design?
Thank you! Easy to find articles on specific topics but such comprehensive ones are rarer. Glad to see this on Flexbox. 🙂
First of all : GREAT article as always! PS. need align-items: stretch (default) – instead align-items: flex-start (default).
Thanks you!
Great article thank you!
https://css-tricks.com/snip…
For the future to be awesome, a couple more things are needed. 😉 But now that the major browsers all support the technique, it indeed is a powerful new technique that will revolutionize layout for websites. Thanks for taking the time to write this excellent tutorial!
Everyone needs leather clothing, whether they are men or women.Ostrich Jackets While simultaneously making one appear fashionable and sophisticated, it also makes one feel at ease.
A scalp vein set called a \”Scalp Van Infusion Set\” is perfect for injecting tiny volumes of infusion solutions into blood samples. Pediatrics and the treatment of individuals with contractures both regularly employ it. The disposable scalp vein set suppliers is used for venipuncture and intravenous infusions.