
Getting Flexy
Flexbox has four key characteristics: direction, alignment, ordering, and flexibility. We'll cover all these characteristics and how they relate by way of a few examples.
The examples are deliberately simplistic; just moving some boxes and their content around so we can understand the principals of how Flexbox works.
Perfect vertically centered text
Note that this first Flexbox example is example_03-03
:

Here's the markup:
<div class="CenterMe"> Hello, I'm centered with Flexbox! </div>
Here is the entire CSS rule that's styling that markup:
.CenterMe { background-color: indigo; color: #ebebeb; font-family: 'Oswald', sans-serif; font-size: 2rem; text-transform: uppercase; height: 200px; display: flex; align-items: center; justify-content: center; }
The majority of the property/value pairs in that rule are merely setting colors and font sizing. The three properties we are interested in are:
.CenterMe { /* other properties */ display: flex; align-items: center; justify-content: center; }
If you have not used Flexbox or any of the properties in the related Box Alignment specification (http://www.w3.org/TR/css3-align/) these properties probably seem a little alien. Let's consider what each one does:
display: flex
: This is the bread and butter of Flexbox. This merely sets the item to be a Flexbox (as opposed to a block, inline-block, and so on).align-items
: This aligns the items within a Flexbox in the cross axis (vertically centering the text in our example).justify-content
: This sets the main axis centring of the content. With a Flexbox row, you can think of it like the button in a word processor that sets the text to the left, right, or center (although there are additionaljustify-content
values we will look at shortly).
OK, before we get further into the properties of Flexbox, we will consider a few more examples.
Tip
In some of these examples I'm making use of the Google hosted font 'Oswald' (with a fallback to a sans-serif font). In Chapter 5, CSS3 – Selectors, Typography, Color Modes, and New Features, we will look at how we can use the @font-face
rule to link to custom font files.
Offset items
How about a simple list of navigation items, but with one offset to one side?
Here's what it looks like:

Here's the markup:
<div class="MenuWrap"> <a href="#" class="ListItem">Home</a> <a href="#" class="ListItem">About Us</a> <a href="#" class="ListItem">Products</a> <a href="#" class="ListItem">Policy</a> <a href="#" class="LastItem">Contact Us</a> </div>
And here is the CSS:
.MenuWrap { background-color: indigo; font-family: 'Oswald', sans-serif; font-size: 1rem; min-height: 2.75rem; display: flex; align-items: center; padding: 0 1rem; } .ListItem, .LastItem { color: #ebebeb; text-decoration: none; } .ListItem { margin-right: 1rem; } .LastItem { margin-left: auto; }
How about that—not a single float, inline-block, or table-cell needed! When you set display: flex;
on a wrapping element, the children of that element become flex-items which then get laid out using the flex layout model. The magic property here is margin-left: auto
which makes that item use all available margin on that side.
Reverse the order of items
Want to reverse the order of the items?

It's as easy as adding flex-direction: row-reverse;
to the wrapping element and changing margin-left: auto
to margin-right: auto
on the offset item:
.MenuWrap { background-color: indigo; font-family: 'Oswald', sans-serif; font-size: 1rem; min-height: 2.75rem; display: flex; flex-direction: row-reverse; align-items: center; padding: 0 1rem; } .ListItem, .LastItem { color: #ebebeb; text-decoration: none; } .ListItem { margin-right: 1rem; } .LastItem { margin-right: auto; }
Simple. Change to flex-direction: column;
on the wrapping element and remove the auto margin:
.MenuWrap { background-color: indigo; font-family: 'Oswald', sans-serif; font-size: 1rem; min-height: 2.75rem; display: flex; flex-direction: column; align-items: center; padding: 0 1rem; } .ListItem, .LastItem { color: #ebebeb; text-decoration: none; }
Want them stacked in the opposite direction? Just change to flex-direction: column-reverse;
and you're done.
Note
You should be aware that there is a flex-flow
property that is shorthand for setting flex-direction
and flex-wrap
in one. For example, flex-flow: row wrap;
would set the direction to a row and set wrapping on. However, at least initially, I find it easier to specify the two settings separately. The flex-wrap
property is also absent from the oldest Flexbox implementations so can render the whole declaration void in certain browsers.
Different Flexbox layouts inside different media queries
As the name suggests, Flexbox is inherently flexible so how about we go for a column list of items at smaller viewports and a row style layout when space allows. It's a piece of cake with Flexbox:
.MenuWrap { background-color: indigo; font-family: 'Oswald', sans-serif; font-size: 1rem; min-height: 2.75rem; display: flex; flex-direction: column; align-items: center; padding: 0 1rem; } @media (min-width: 31.25em) { .MenuWrap { flex-direction: row; } } .ListItem, .LastItem { color: #ebebeb; text-decoration: none; } @media (min-width: 31.25em) { .ListItem { margin-right: 1rem; } .LastItem { margin-left: auto; } }
You can view that as example_03-05
. Be sure to resize the browser window to see the different layouts.
Inline-flex
Flexbox has an inline variant to complement inline-block and inline-table. As you might have guessed it is display: inline-flex;
. Thanks to its beautiful centering abilities you can do some wacky things with very little effort.

Here's the markup:
<p>Here is a sentence with a <a href="http://www.w3.org/TR/css-flexbox-1/#flex-containers" class="InlineFlex">inline-flex link</a>.</p>
And here is the CSS for that:
.InlineFlex { display: inline-flex; align-items: center; height: 120px; padding: 0 4px; background-color: indigo; text-decoration: none; border-radius: 3px; color: #ddd; }
When items are set as inline-flex
anonymously (for example, their parent element is not set to display: flex;
) then they retain whitespace between elements, just like inline-block or inline-table do. However, if they are within a flex container, then whitespace is removed, much as it is with table-cell items within a table.
Of course, you don't always have to center items within a Flexbox. There are a number of different options. Let's look at those now.
Flexbox alignment properties
If you want to play with this example, you can find it at example_03-07
. Remember the example code you download will be at the point where we finish this section so if you want to 'work along' you may prefer to delete the CSS in the example file and start again.
The important thing to understand with Flexbox alignment is the concept of axis. There are two axis to consider, the 'main axis' and the 'cross axis'. What each of these represents depends upon the direction the Flexbox is heading. For example, if the direction of your Flexbox is set to row
, the main axis will be the horizontal axis and the cross axis will be the vertical axis.
Conversely, if your Flexbox direction is set to column
, the main axis will be the vertical axis and the cross axis will be the horizontal.
The specification (http://www.w3.org/TR/css-flexbox-1/#justify-content-property) provides the following illustration to aid authors:

Here's the basic markup of our example:
<div class="FlexWrapper"> <div class="FlexInner">I am content in the inner Flexbox.</div> </div>
Let's set basic Flexbox related styles:
.FlexWrapper { background-color: indigo; display: flex; height: 200px; width: 400px; } .FlexInner { background-color: #34005B; display: flex; height: 100px; width: 200px; }
In the browser, that produces this:

Right, let's test drive the effects of some of these properties.
The align-items
property positions items in the cross axis. If we apply this property to our wrapping element like so:
.FlexWrapper { background-color: indigo; display: flex; height: 200px; width: 400px; align-items: center; }
As you would imagine, the item within that box gets centered vertically:

The same effect would be applied to any number of children within.
Sometimes, you may want to pull just one item into a different alignment. Individual flex items can use the align-self
property to align themselves. At this point, I'll remove the previous alignment properties, add another two items into the markup (they have been given the .FlexInner
HTML class), and on the middle one I'll add another HTML class (.AlignSelf
) and use it to add the align-self
property. Viewing the CSS at this point may be more illustrative:
.FlexWrapper { background-color: indigo; display: flex; height: 200px; width: 400px; } .FlexInner { background-color: #34005B; display: flex; height: 100px; width: 200px; } .AlignSelf { align-self: flex-end; }
Here is the effect in the browser:

Wow! Flexbox really makes these kinds of changes trivial. In that example the value of align-self
was set to flex-end
. Let's consider the possible values we could use on the cross axis before looking at alignment in the main axis.
For cross axis alignment, Flexbox has the following possible values:
flex-start
: Setting an element toflex-start
would make it begin at the 'starting' edge of its flex containerflex-end
: Setting toflex-end
would align the element at the end of the flex containercenter
: Puts it in the middle of the flex containerbaseline
: Sets all flex items in the container so that their baselines alignstretch
: Makes the items stretch to the size of their flex container (in the cross axis)
Note
There are some particulars inherent to using these properties, so if something isn't playing happily, always refer to the specification for any edge case scenarios: http://www.w3.org/TR/css-flexbox-1/.
Alignment in the main axis is controlled with justify-content
(for non Flexbox/block-level items, the justify-self
property has also been proposed (http://www.w3.org/TR/css3-align/). Possible values for justify-content
are:
flex-start
flex-end
center
space-between
space-around
The first three do exactly what you would now expect. However, let's take a look what space-between
and space-around
do. Consider this markup:
<div class="FlexWrapper"> <div class="FlexInner">I am content in the inner Flexbox 1.</div> <div class="FlexInner">I am content in the inner Flexbox 2.</div> <div class="FlexInner">I am content in the inner Flexbox 3.</div> </div>
And then consider this CSS. We are setting the three flex-items (FlexInner
) to each be 25% width, wrapped by a flex container (FlexWrapper
) set to be 100% width.
.FlexWrapper { background-color: indigo; display: flex; justify-content: space-between; height: 200px; width: 100%; } .FlexItems { background-color: #34005B; display: flex; height: 100px; width: 25%; }
As the three items will only take up 75% of the available space, justify-content
explains what we would like the browser to do with the remaining space. A value of space-between
puts equal amount of space between the items and space-around
puts it around. Perhaps a screenshot here will help: This is space-between
.

And here is what happens if we switch to space-around
.

Those two values are pretty handy I think you will agree.
Tip
The various alignment properties of Flexbox are currently being specified into the CSS Box Alignment Module Level 3. This should give the same fundamental alignment powers to other display properties, such as display: block;
and display: table;
. The specification is still being worked upon so check the status at http://www.w3.org/TR/css3-align/.
The flex property
We've used the width
property on those flex-items but it's also possible to define the width, or 'flexiness' if you will, with the flex
property. To illustrate, consider another example; same markup, but amended CSS for the items:
.FlexItems { border: 1px solid #ebebeb; background-color: #34005B; display: flex; height: 100px; flex: 1; }
The flex
property is actually a shorthand way of specifying three separate properties: flex-grow
, flex-shrink
, and flex-basis
. The specification covers these individual properties in more detail at http://www.w3.org/TR/css-flexbox-1/. However, the specification recommends that authors use the flex
shorthand property, so that's what we're rolling with here, capiche?

For flex-items, if a flex
property is present (and the browser supports it), it is used to size the item rather than a width or height value (if present). Even if the width or height value is specified after the flex
property, it will still have no effect. Let's look at what each of these values do.
flex-grow
(the first value you can pass to flex) is the amount, relevant to the other flex items, the flex-item can grow when free space is availableflex-shrink
is the amount the flex-item can shrink relevant to the other flex-items when there is not enough space availableflex-basis
(the final value you can pass to Flex) is the basis size the flex-item is sized to
Although it's possible to just write flex: 1
, I recommend writing all the values into a flex
property. I think it's clearer what you intend to happen. For example: flex: 1 1 auto
means that the item will grow into 1 part of the available space, it will also shrink 1 part when space is lacking and the basis size for the flexing is the intrinsic width of the content (the size the content would be if flex wasn't involved).
Let's try another: flex: 0 0 50px
means this item will neither grow nor shrink and it's basis is 50px (so it will be 50px regardless of any free space). How about flex: 2 0 50%—that's going to take two 'lots' of available space, it won't shrink and its basis size is 50%. Hopefully, these brief examples have demystified the flex property a little.
You can think of the flex
property as a way to set ratios. With each flex-item set to 1, they each take an equal amount of space:

Right, so to test the theory, let's amend the HTML classes in the markup:
<div class="FlexWrapper"> <div class="FlexItems FlexOne">I am content in the inner Flexbox 1.</div> <div class="FlexItems FlexTwo">I am content in the inner Flexbox 2.</div> <div class="FlexItems FlexThree">I am content in the inner Flexbox 3.</div> </div>
And then here is the amended CSS:
.FlexItems { border: 1px solid #ebebeb; background-color: #34005B; display: flex; height: 100px; } .FlexOne { flex: 1.5 0 auto; } .FlexTwo, .FlexThree { flex: 1 0 auto; }
In this instance, FlexOne
takes up 1.5 the amount of space that FlexTwo
and FlexThree
take up.
This shorthand syntax really becomes useful for quickly bashing out relationships between items. For example, if the request comes in, "that needs to be 1.8 times wider than the others", you could easily facilitate that request with the flex property.
Hopefully, the incredibly powerful flex property is starting to make a little sense now?
I could write chapters and chapters on Flexbox! There are so many examples we could look at. However, before we move on to the other main topic of this chapter (responsive images) there are just two more things I would like to share with you.
Simple sticky footer
Suppose you want a footer to sit at the bottom of the viewport when there is not enough content to push it there. This has always been a pain to achieve but with Flexbox it's simple. Consider this markup (which can be viewed in example_03-08
):
<body> <div class="MainContent"> Here is a bunch of text up at the top. But there isn't enough content to push the footer to the bottom of the page. </div> <div class="Footer"> However, thanks to flexbox, I've been put in my place. </div> </body>
And here's the CSS:
html, body { margin: 0; padding: 0; } html { height: 100%; } body { font-family: 'Oswald', sans-serif; color: #ebebeb; display: flex; flex-direction: column; min-height: 100%; } .MainContent { flex: 1; color: #333; padding: .5rem; } .Footer { background-color: violet; padding: .5rem; }
Take a look at that in the browser and test adding more content into .MainContentdiv
. You'll see that when there is not enough content, the footer is stuck to the bottom of the viewport. When there is, it sits below the content.
This works because our flex
property is set to grow where space is available. As our body is a flex container of 100% minimum height, the main content can grow into all that available space. Beautiful.
Changing source order
Since the dawn of CSS, there has only been one way to switch the visual ordering of HTML elements in a web page. That was achieved by wrapping elements in something set to display: table
and then switching the display
property on the items within, between display: table-caption
(puts it on top), display: table-footer-group
(sends it to the bottom), and display: table-header-group
(sends it to just below the item set to display: table-caption
). However, as robust as this technique is, it was a happy accident, rather than the true intention of these settings.
However, Flexbox has visual source re-ordering built in. Let's have a look at how it works.
Consider this markup:
<div class="FlexWrapper"> <div class="FlexItems FlexHeader">I am content in the Header.</div> <div class="FlexItems FlexSideOne">I am content in the SideOne.</div> <div class="FlexItems FlexContent">I am content in the Content.</div> <div class="FlexItems FlexSideTwo">I am content in the SideTwo.</div> <div class="FlexItems FlexFooter">I am content in the Footer.</div> </div>
You can see here that the third item within the wrapper has a HTML class of FlexContent
—imagine that this div
is going to hold the main content for the page.
OK, let's keep things simple. We will add some simple colors to more easily differentiate the sections and just get these items one under another in the same order they appear in the markup.
.FlexWrapper { background-color: indigo; display: flex; flex-direction: column; } .FlexItems { display: flex; align-items: center; min-height: 6.25rem; padding: 1rem; } .FlexHeader { background-color: #105B63; } .FlexContent { background-color: #FFFAD5; } .FlexSideOne { background-color: #FFD34E; } .FlexSideTwo { background-color: #DB9E36; } .FlexFooter { background-color: #BD4932; }
That renders in the browser like this:

Now, suppose we want to switch the order of .FlexContent
to be the first item, without touching the markup. With Flexbox it's as simple as adding a single property/value pair:
.FlexContent { background-color: #FFFAD5; order: -1; }
The order
property lets us revise the order of items within a Flexbox simply and sanely. In this example, a value of -1
means that we want it to be before all the others.
Let's combine our new source order changing powers with some media queries to produce not just a different layout at different sizes but different ordering.
As it's generally considered wise to have your main content at the beginning of a document, let's revise our markup to this:
<div class="FlexWrapper"> <div class="FlexItems FlexContent">I am content in the Content.</div> <div class="FlexItems FlexSideOne">I am content in the SideOne.</div> <div class="FlexItems FlexSideTwo">I am content in the SideTwo.</div> <div class="FlexItems FlexHeader">I am content in the Header.</div> <div class="FlexItems FlexFooter">I am content in the Footer.</div> </div>
First the page content, then our two sidebar areas, then the header and finally the footer. As I'll be using Flexbox, we can structure the HTML in the order that makes sense for the document, regardless of how things need to be laid out visually.
For the smallest screens (outside of any media query), I'll go with this ordering:
.FlexHeader { background-color: #105B63; order: 1; } .FlexContent { background-color: #FFFAD5; order: 2; } .FlexSideOne { background-color: #FFD34E; order: 3; } .FlexSideTwo { background-color: #DB9E36; order: 4; } .FlexFooter { background-color: #BD4932; order: 5; }
Which gives us this in the browser:

And then, at a breakpoint, I'm switching to this:
@media (min-width: 30rem) { .FlexWrapper { flex-flow: row wrap; } .FlexHeader { width: 100%; } .FlexContent { flex: 1; order: 3; } .FlexSideOne { width: 150px; order: 2; } .FlexSideTwo { width: 150px; order: 4; } .FlexFooter { width: 100%; } }
Which gives us this in the browser:

Note
In that example, the shortcut flex-flow: row wrap
has been used. That allows the flex items to wrap onto multiple lines. It's one of the poorer supported properties, so depending upon how far back support is needed, it might be necessary to wrap the content and two side bars in another element.
Wrapping up Flexbox
There are near endless possibilities when using the Flexbox layout system and due to its inherent 'flexiness', it's a perfect match for responsive design. If you've never built anything with Flexbox before, all the new properties and values can seem a little odd and it's sometimes disconcertingly easy to achieve layouts that have previously taken far more work. To double-check implementation details against the latest version of the specification, make sure you check out http://www.w3.org/TR/css-flexbox-1/.
I think you'll love building things with Flexbox.
Note
Hot on the heels of the Flexible Box Layout Module is the Grid Layout Module Level 1: http://www.w3.org/TR/css3-grid-layout/.
It's relatively immature compared to Flexbox (much like the early history of Flexbox, grid layout has already been through some major changes) and as such we aren't looking at it in detail here. However, it's definitely one to keep an eye on as it promises us even more layout powers.