When I first started building websites in the mid-nineties, the only reliable way to layout a page was to use tables. This created a large amount of markup, a plethora of spacer.gif images and to be perfectly honest, it was a hack. We were using markup designed for laying out tabular data to layout a web page. But the means to layout a website that early in the web industry simply didn’t exist so we made do with what we could.
And then CSS & floats happened. Again, a hack as floats had been designed to ’float’ chunks of content to the left or right of articles like block quotes or asides. But again, we as the web industry utilised the markup for layout. At this point, a new-dedicated-layout markup tool was required. Something that was easy to grasp and easy to build with. That tool is flex box.
Flex box is currently at Release Candidate stage so the W3C are actively urging browser makers to implement flex box in their software. So far, the latest version of Chrome supports flexbox using the -webkit prefix. The latest version of Opera also supports flexbox and that’s prefix free. Forthcoming Firefox 20 will support flexbox ‘prefix free’ but at the moment, it only offers partial support. It’s worth keeping an eye out on caniuse.com to keep on top of the support for flexbox.
So flexbox is almost ready for use in the real world but just because the support isn’t quite there, doesn’t mean you can’t familiarise yourself with the code syntax because I promise you, you’ll be using flex box by the end of 2013!
So what’s flex box good for? Layouts primarily but its ideal for anything where you’d want to arrange items within a container and not have to rely on floats or setting things as inline.
Flexbox is made up of two core components, the flexbox container and flexbox items. As you can imagine, the container is effectively the wrapper element and the items within are the direct children of the flexbox container. Flexbox requires both a container and items for it to work properly.
To set up your container, you simply wrap your content in a div or other semantic markup tag and set the CSS to display: flex; that’s it! So now any direct children to that div will become the flexbox Items.
<!-- this is the flexbox container -->
<div class="container">
<!-- these are the flexbox items -->
<div class="item">First Item</div>
<div class="item">Second Item</div>
<div class="item">Third Item</div>
</div>
.container {
display: flex;
}
Flexbox, by default orders Flex items from left to right, top to bottom. This is the ‘main axis’ and it relates to the direction of the axis. The axis perpendicular to the ‘main axis’ is called the ‘cross axis’. This is one of the most important things to remember when playing with Flexbox. The ‘main axis’ is the direction your flex items are going in. If they’re running horizontally, then your main axis is horizontal and your cross axis is vertical. The opposite applies if your flex items are running vertically.
In order to adjust the direction of your Flexbox, you need to set the CSS attribute of your flexbox container to one of the following: –
flex-direction: row / row-reverse / column / column-reverse;
row
Is the default value for flex-direction. The other three options are pretty self explanatory.
So how many of you reading are thinking “flexbox doesn’t sound that great so far; I can do this already using inline-block” – and you’d be quite right… so far.
Justify!
The next fun thing I’ll point out is the ‘justify-content’ declaration which gets applied to your flexbox container. This declaration controls the layout of your flex items within the container. The default value here is ‘flex-start’ which means it’ll start at the top left of your flex container or where your content would generally start. The justify-content declaration also accepts the following values: –
flex-end
– Content flows from the opposite end to the flex-start.
center – content is aligned to the center and spreads out as you would expect equally.
The above three values all take padding & margins on the ‘flex-items’ into account when calculating the display. The following two values work out their own spacing.
space-between
– This takes the first flex item and places it at the start. It then takes the last flex item and places it at the end. It’ll then calculate how many other items are to be displayed along with the additional space left to use and spread the items out equally between the first & last.
That sounds confusing so here’s a quick example.
space-around
– will take the total width of the flex container, less the total width of the flex items and share the remaining space equally between items.
Cross alignment
So now that you’ve got the alignment on your main axis sorted, it’s time to take a look at that cross axis position. The declaration ‘align-items’ can be applied to your flexbox container and it will align your items along the cross axis. To make that clear, if the ‘main axis’ is from left to right (horizontal) then your ‘align-items’ declaration will work on your vertical alignment.
align-items
accepts five values which are all pretty similar to the justify-content
values.
flex-start
is the default value and will align items at the start (or in this case, the top).
flex-end
will align items at the end (or in this case, the bottom).
center
will-obviously-center the items on the cross axis.
baseline
is a little harder to explain but fundamentally, it’ll align all your flex-items based on the baseline of the content within.
stretch
is the last of the five accepted values and this one is pretty cool. Essentially, it stretches your items out so that fill the container height. That option alone will certainly get some developers ^really^ interested in playing with flexbox.
There’s no more room at the inn
So what happens if the flex items–with their specified widths–over run the flex container? by default, they’ll overflow and spill out of the sides. That’s not really an ideal solution but fortunately, there is a declaration that’ll help.
flex-wrap
controls how the items will wrap within the flex container. ‘nowrap’ is the default and as explained above, will overflow if the flex items exceed the container.
Setting flex-wrap: wrap; will make the items wrap inside the container and will prove useful in the future layouts we code.
The third value which we can use is flex-wrap: wrap-reverse; which, as you can imagine, reverses the flow of items, but still wraps them.
Align-Content
Earlier, I spoke about justify-content which aligns your flex items across the ‘main axis’. Align content is the same declaration but for the cross axis and it’ll accept pretty much the same values as before.
align-content: stretch;
is the default and as you would expect, stretches the items out across the cross axis.
align-content: flex-start;
aligns the items to the start of the cross-axis.
align-content: flex-end;
is the opposite and aligns items at the end of the cross-axis.
align-content: center;
will align your items centrally.
align:content: space-around / space-between;
will spread out your items equally utilising all the available space as described before.
The Items
So far, all the declarations I’ve spoken about are for the flex container and detail how we can lay out the items within. But that’s only half the fun. There are a whole slew of declarations aimed at the items too!
Order
This is a cool little declaration that’ll allow you to change and / or upset the order of which your flex items are displayed. You can move a flex item up or down the hierarchy by using positive or negative values within the ‘order’ declaration. Adding order: -1; to one of your flex-items will move it down the list. Think of it as a z-index but for the x axis.
Changing the order in CSS doesn’t change the order in the HTML so screen-readers will read out your items as the HTML, not the re-ordered flexbox version.
Margin in the middle
Flexbox also has it’s own take on the margin declaration. You can use declarations such as margin: auto; on a single item within a flex container and it’ll position that single item slap bang in the middle of the container. I can see that coming in really handy! Gone are the days of using JS to centrally align a div on a page.
Conclusion
And there you have it, a whistle-stop look at the future of web layouts. I think we’ve finally got our web layout markup tool that we’ve always wanted. We no longer need to hack existing code and shoe-horn layouts into markup that was designed for typographical nuances.
Flexbox, once fully supported will be the way of handling our layouts and it’s going to be a really powerful tool too.
I hope this article has given you some insight into flexbox and has primed you ready for use. I urge you to grab the latest version of Google Chrome (if you don’t already have it) and play around to truly appreciate the power and opportunities that await.