Flexbox is, rightly, the display property you should now be using to lay out pages. Hopefully no-one reading this will still be using tables to lay out pages. Although what needs taking into account is that, actually, using table to lay out pages made a lot of sense in some respects. Along came CSS boxes though and there was much rejoicing.
Using the box model as it was, though, was often horribly complex and required far too much work for little reward. One huge problem was the absolute values for padding, margin and border; all of which affected the width of a box. A simple piece of code such as:
border 1px solid #000;
padding: 0 5px;
would give a box that was 50% of its parent, plus(!), 2 pixels for the border and 10 pixels for padding. Granted, the way around this is to set the padding as a percentage value, but doing this invariably requires some mind-numbing mathematical problems.
A great way around this is to use the flexbox solution.
Flexbox, brings a new display property: box, to the table with eight properties. W3C define this new tool as follows:
“… The children of a box are laid out either horizontally or vertically, and unused space can be assigned to a particular child or distributed among the children by assignment of ‘flex’ to the children that should expand. Nesting of these boxes … can be used to build layouts in two dimensions.”
The flexbox model improves on the old box model and, while it lacks many of the more complex formatting properties used previously, makes up for that in simpler, more powerful tools. These properties are still undergoing some change in the working draft with some being expanded: box-flex has become flex-grow and flex-shrink, while others are still being combined: box-orient and box-direction have become flex-direction. Indeed, anything that was previously ‘box-‘ is being changed to ‘flex-‘.
By using flexbox, you will need to use an extra div or two. The parent of any flexbox element will have ‘display’ set to ‘box’. This means some small extra presentational mark-up is often required but is no big deal. Over the next few paragraphs, some of the new features will be explored in greater detail.
The basics: very little can be achieved without it and this simply tells the browser to resize an element when the element is too big or small for its parent. For example, you may have a container with three children positioned side-by-side. If you want them to fit within the parent without ‘spilling’ over the sides, then you will need to specify either exact pixel widths – highly inflexible – or to work in percentages and the requisite horrible calculations this involves.
By setting the parent to ‘display: box’ and each aside to ‘box-flex: 1’ then the browser takes care of the maths automatically and renders them as three equal sized boxes, fitting snugly within the container.
‘Box-flex’ will automatically size the boxes based on the amount of unused space (even if this is a negative number i.e., the boxes are larger than the parent). The value of ‘1’ assigned to each box in the previous example indicates the ratio, so with all set to ‘1’ they are scaled equally.
This is invaluable for flexible layouts, primarily due to the fact that all padding, margin and border values are honored. The browser does all the work figuring the optimum size, based on the size of the parent. The beauty of ratios also means that the boxes can be sized differently without awful calculations, e.g., 2:1:1, or 3:1:2.
Animating Flexible Boxes
Simple and elegant effects are readily available for this purpose. Just make the ‘li’ elements in a navigation bar, for example, flexible and specify the width on ‘:hover’ and a nice effect can be achieved where the highlighted element expands at the expense of the other elements.
Equal Height Columns
Happily, all flex-box elements have inherited a default value of ‘box-align: stretch’. This means they will always stretch to fill their container. For example, two flexbox columns in a parent will always be the same height.
Box-orient and box-direction
These essential parts of the model are set to be merged into the new ‘flex-direction’ property which will use the following values:
Of which, all are pretty clear and self-explanatory.
This is an incredibly useful that lets you control the order in which boxes are displayed. The value is set so that the lower the number the higher the priority. So anything with the property ‘box-ordinal-group: 1’ will be rendered first. IF several elements have the same integer, then they will be rendered in the order they appear in the html. The perfect example of this in use is for blog posts that have been ‘stickied’: by simply setting the value at 1, then it will appear first in the container regardless of its position within the code.
Box-pack and box-align
These two properties help to position the boxes on the page. While the default value is to ‘stretch’ there are times when an element might call for being centered. By setting the ‘box-align’ to ‘center’ the element will be centered either vertically or horizontally depending on its ‘box-orient’ value.
Box-pack is another alignment property. This enables the alignment of elements on an axis perpendicular to the axis they are laid out on. Basically, it allows the horizontal (or vertical) alignment of an element that have already been aligned.
So flexbox proves to be another exciting addition to the W3C Working Draft. This should be used sparingly, as it’s at the very cutting edge of development there may still be teething issues. However, through experimentation and working at the very edges of what is possible, this promises to be an exciting way of laying out pages.
Breaking free of ‘floating’ elements will provide developers with more flexibility in their layout.
Itera Research Team