CSS3 Flexible Box Layout Module (aka Flex Box) introduction and demos/test cases

Doing layouts on the web has always been hard, but it seems like we’re getting a better option to do it now.

Background

First, we had tables for layout, and while semantically incorrect, with proper nesting and other tricks, we could build fairly functional layouts with them.

Then along came floats which most of the people are using today. We can use any element we want to, but floats aren’t really for the fainthearted. On surface it seems pretty basic, but the complex functionality behind can make seasoned developers look dumbfounded at their screens. Also, one of the downsides with floats is needing to clear them through extra clear elements or, better, clear CSS floats without extra markup.

Downside with that, though, besides from it’s not that easy to grasp floats, is that we need various trickery to support equal-height columns, since there’s no default way to set up a relationship between elements with floats.

Then some people have started using display: table, display: table-cell etc, but since support took so long to get in Internet Explorer (IE8), people seemed to give up on it and just accept floats as the de-facto solution.

Introducing Flexible Box Layout Module (aka Flex Box)

One hidden gem that most people seem to have missed is the Flexible Box Layout Module. It offers:

  • Equal-height columns.
  • Source-order independence for elements.
  • Specifying a relation between elements.
  • Flexible size and alignment of content.

A simple example

Let’s say we want to display three columns next to each other. It would then look like this:

<div class="flex-container">
	<div class="col-1">I am column 1</div>
	<div class="col-2">I am column 2</div>
	<div class="col-3">I am column 3</div>
</div>
.flex-container {
	display: -moz-box;
	display: -webkit-box;
	display: box;
	-moz-box-orient: horizontal;
	-webkit-box-orient: horizontal;
	box-orient: horizontal;
}	

We’re using the display property to set the containing element to a box, and then we use the box-orient property to set it to be horizontal (you could also use vertical).

With this approach, the direct child elements (i.e. <div class=”col-1″> etc) will be laid out next to each other, with their width set to their contents. But what if we want them to together expand out the entire parent width, in a flexible manner? Then we need to apply box-flex to them:

.col-1 {
	-moz-box-flex: 1;
	-webkit-box-flex: 1;
	box-flex: 1;
}

.col-2 {
	-moz-box-flex: 1;
	-webkit-box-flex: 1;
	box-flex: 1;
}

.col-3 {
	-moz-box-flex: 2;
	-webkit-box-flex: 2;
	box-flex: 2;
	
}

The value of the box-flex property is about how the remainder of the width is divided by the elements, as explained in Zoe’s comment, where a larger number means wider. It also means that each element can afford having a padding, which won’t make them become too wide (great, right?).

Setting presentation order

We have two ways of setting presentation order, which is through the box-direction property on the parent element (i.e. the one with the display: box property set), or we can use box-ordinal-group to give each column/child element a number which is in the order they will be visually represented (interestingly enough, in Firefox this also aligns the elements to the right, but in Google Chrome and Safari they are to the left):

.flex-container-reverse {
	display: -moz-box;
	display: -webkit-box;
	display: box;
	-moz-box-orient: horizontal;
	-webkit-box-orient: horizontal;
	box-orient: horizontal;
	-moz-box-direction: reverse;
	-webkit-box-direction: reverse;
	box-direction: reverse;
}

meaning they are presented in a reversed order, or:

.col-1 {
	-moz-box-ordinal-group: 2;
	-webkit-box-ordinal-group: 2;
	box-ordinal-group: 2;
}

.col-2 {
	-moz-box-ordinal-group: 3;
	-webkit-box-ordinal-group: 3;
	box-ordinal-group: 3;
}

.col-3 {
	-moz-box-ordinal-group: 1;
	-webkit-box-ordinal-group: 1;
	box-ordinal-group: 1;
}	

where col-3 is presented first, then col-1 and finally col-2 at the end.

Centering and justifying

We have another interesting property, box-pack, which we can use to specify how the boxes should be presented, e.g. centered, justified etc. This would center the three of them within their parent element (interestingly, the previously set padding now disappears):

.flex-container-center {
	display: -moz-box;
	display: -webkit-box;
	-moz-box-orient: horizontal;
	-webkit-box-orient: horizontal;
	box-orient: horizontal;
	-moz-box-pack: center;
	-webkit-box-pack: center;
	box-pack: center;
}

We could also justify the three elements evenly within their parent:

.flex-container-justify {
	display: -moz-box;
	display: -webkit-box;
	display: box;
	-moz-box-orient: horizontal;
	-webkit-box-orient: horizontal;
	box-orient: horizontal;
	-moz-box-pack: justify;
	-webkit-box-pack: justify;
	box-pack: justify;
}	

However, justifying only seems to work properly in WebKit-based web browsers (Google Chrome and Safari).

Flexible Box Layout Demo

As part of my ongoing CSS3 test suite, I have added a number of CSS3 Flexible Box Layout Module examples and test cases, where you can see the tests in your web browser, the code being used and also the possibility to change it and see what happens.

Web browser support

  • Firefox 3.0+
  • Google Chrome 5.0+
  • Safari 3.2+
  • iOS 3.2+ (Mobile Safari)
  • Android 2.2+

That’s a pretty good web browser base, but unfortunately there’s still no trace of support in the beta of Internet Explorer 9 or beta of Opera 11, but I do hope it catches on there too, because we really need another alternative for creating layouts on the web.

Related reading

Posted in CSS,Developing,Technology,Web browsers |

27 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>