Practical Examples of the Flexible Box Model

If there’s one thing in CSS3 that really gives me warm fuzzies, it’s the flexible box model. What it does is provides a way to create many layout affects that otherwise would require workarounds with float or positioning or both. And there are many types of layouts that without out it would require JavaScript to create the same effect. Sadly, at present the flexible box model is only implemented in Firefox, Safari and Chrome. As it turns out, Microsoft’s IE team approached the W3C standards teams with a proposal for a grid-based layout module. It appears to be based on experience implementing the Silverlight grid layout system, which is a good thing. Silverlight grids are a powerful layout tool and is the most important feature for creating interfaces with Silverlight. Because this grid proposal is very solid, the W3C has dropped all further work on the flexible box model and instead are moving ahead in finalizing the draft for the grid layout module. If you read that speck, you’ll realize how much we need a CSS grid system. For now, however, we do have the flexible box model working in Firefox, Chrome and Safari, as well as on mobile Webkit, which includes iOS, Android, WebOS, and Blackberry. This means that if you’re doing mobile development you can use the flexible box model today to help you implement your layout needs. Once you start using the flexible box model, you’ll hate having to go back to situations where it’s not available.

The flexible box model got a lot of attention from a post by Alex Russell back in August 2009. The good thing is that in his post he showed some of the practical things that the flexible box model addresses and provided a stylesheet with a small subset of the flexible box model properties that people could use right away. His post has been replicated and linked to all over the Web. Unfortunately a lot of people who are not familiar with the spec for the flexible box model are under the impression that what’s in his stylesheet is it. So, with that in mind I’m loosing another stylesheet on the public that allows a greater utilization of the flexible box model. I’ll also give you a layout where a lot of these are in use so that you can see how they work.

Before I get going let me say this. The flexible box model is not perfect. It isn’t supported by IE9 or Opera. And now it looks like the W3C is bypassing it for a more robust grid system. Personally, I’d like to see something like the Silverlight grid system combined with aspects of the flexible box model. That would be the best of both approaches. If you’re targeting the mobile Web, in other words you intend on target Webkit browsers, you can expect robust support for the flexible box model. I doubt it’s going to go away just because the W3C doesn’t include it in any recommendation. I expect it to remain in Webkit for the foreseeable future because it’s already been in use for a number of years.

The flexible box model is about the way a collection of child nodes gets laid out in relation to each other and their parent node. To achieve its layout goals, the flexible box model offers properties for the parent node as well as for the child nodes that determine the layout characteristics of the child nodes.

To work with the flexible box model you need to define its display property to box:

1
2
3
4
#myDiv {
    display: -webkit-box;
    display: -moz-box;
}

Elements with display set to box can order their child nodes in two orientations: vertical or horizontal. If no orientation is provided, the box defaults to vertical:

1
2
3
4
5
6
#myDiv {
    display: -webkit-box;
   -webkit-box-orient: horizontal;
    display: -moz-box;
    -moz-box-orient: horizontal;
}

Besides defining the orientation, you can also designate what direction the child elements stack, either normal or reverse. A box direction of reverse means the elements display in the opposite order in which they physically appear in the document, so that the first would be last and the last first. By default the box direction is normal stacking order.

Then there is the packing order. This allows you to define how the child elements are packed inside the parent. By default they are packed in from the beginning of the parent. For vertical orientation this is the top and for horizontal orientation this is the left. Other packing orders are end, center and justify. If the packing order is end, for a vertical orientation the elements will stack up from the bottom. For a box with horizontal alignment, the boxes will stack from the right. A packing order of center means that for vertical orientation the child elements will be centered vertical with any left over space displayed equally at the top and bottom. For horizontal orientation a packing order of center means the elements are centered horizontally with left over space equally divided on the left and right. A packing order of justified means that any available space is spread equally between the child elements, for vertical orientation this is vertical spacing, and for horizontal orientation this is horizontal spacing.

Box-align-start

A box with alignment set to “start”

box-align-end

A box with alignment set to “end”

box-align-center

A box with alignment set to “center”

And elements can have their box alignment defined. The default is stretch. This stretches the dimensions of the child elements to fill the parent box. If the alignment is start, for horizontal orientation the elements are aligned to the top of the parent. If the orientation is vertical, they are aligned to the left of the parent. An alignment of end will align elements with horizontal alignment to the bottom of the parent. With vertical orientation they will be aligned to the right of the parent. An alignment of center will align horizontal elements along the horizontal center of the parent and for vertical orientation it will center them along the vertical center of the parent. There is also an alignment of baseline, but this is only for horizontal orientation. It aligns the elements along their horizontal baseline.

Then there is a set of properties that you can define on the child elements. These are flex and ordinal group. The flex property tells the browser how to deal with the dimensions of the child element. If you have three child elements and they don’t fill their parent, giving one of the a value of flex:1 will cause that element to take up all the left over space. If you gave one element flex: 1 and another one flex: 2, the available space would be divided up such that the element with flex: 1 would get one third of the available space and the element with flex: 2 would get two thirds of the available space. Of course the element with no flex value would default to whatever its width is. The ordinal group property allows you to designate groups of elements so that they appear in a different order than their document order. I’m not so sure about the practical use for this property. I’ve thought about it for months and have not been able to come up with a use case where I would need it. But it’s there.

I’ve created a flexible box model stylesheet with classes for all the various box properties. This means you can add the classes to an element to build out the definition you need for an element. I’ve also put together a interactive test case where you can dynamically toggle a number of the box properties and see their effect in real time. You can try it out online if you’re using Firefox, Chrome or Safari, or you can download the working example to dissect and learn.

Leave a comment