Flexible Box Layout
Part 1. Old Implementations
Streamline Web development workflow presumes the existence of a layout system allowing Web authors to align HTML elements in any direction and "flex" them to utilize available dimensions of a Web page. CSS 2.1 exposed four layout models: block layout, inline layout aimed at stylizing text, table layout used to display tabular data, and positioned layout with the explicit settings of an element's coordinates. To create an elastic page design, developers had to combine CSS with JavaScript code blocks or to resort to ready CSS framework solutions. But CSS/JS frameworks usually contains a set of style and script files, and this can slow down performance, especially in the world of the mobile Web. Using CSS frameworks in cross-platform mobile apps development is not very efficient, either: using a bunch of external files in, let us say, Android's WebView occupies a large amount of memory and uses device's CPU too intensely. So CSS3 flexible box layout is a really welcomed CSS enhancement facilitating the creation of complex applications and Web pages. Browser vendors have implemented flexbox-related properties in their products. However, there are two distinctive implementations of this type of layout. The newer implementation based on the current W3C Flexible Box Layout specification is already available in almost all of major desktop browsers. The older implementation is still supported in Chrome, Safari, Firefox and Android native browser. It will be the topic of our first article.
Terminology
First of all, let's define a few terms which will be referred to later.
flex container
An element with display: flex or display: inline-flex CSS declaration. The declarations targeting the old flexbox implementation use the prefixed box or inline-box values:
<style>
#flex-container {
display: -webkit-box;
display: -moz-box;
}
</style>
. . .
<div id="flex-container">
<!-- flex items -->
<div><img src="red-ball.png"/></div>
<div><img src="green-ball.png"/></div>
<div><img src="blue-ball.png"/></div>
</div>
Here's an example of a declaration using new flexible box properties:
<style>
#modern-flex-container {
display: flex;
display: -webkit-flex;
display: -ms-flexbox;
}
</style>
. . .
<div id="modern-flex-container">
<!-- flex items -->
<div><img src="red-ball.png"/></div>
<div><img src="green-ball.png"/></div>
<div><img src="blue-ball.png"/></div>
</div>
In both cases the visual layout of three <div> elements looks like this:
flex item
Child element of a flex container. In the example above three <div> elements are flex items laid out according to the flexible layout model.
main axis
Axis along which flex items are laid out. The direction of the axis is set with the help of the flex-direction property (in the old implementation the main axis direction is defined by the prefixed box-orient).
cross axis
Axis perpendicular to the main axis. if flex direction of a flex container is horizontal, its main axis is horizontal, too; its cross axis is vertical:
Flexible Box Layout Properties
Here's a summary table of old flexible box layout properties and their respective values.
-webkit | -moz | values |
---|---|---|
-webkit-box-align | -moz-box-align | baseline center end start stretch |
-webkit-box-direction | -moz-box-direction | normal reverse |
-webkit-box-flex | -moz-box-flex | floating-point flex value |
-webkit-box-flex-group | not supported | group number of the flexible element |
-webkit-box-lines | not supported | multiple single |
-webkit-box-ordinal-group | -moz-box-ordinal-group | ordinal group number of the element. |
-webkit-box-orient | -moz-box-orient | block-axis horizontal inline-axis vertical |
-webkit-box-pack | -moz-box-pack | center end justify start |
-webkit-box-align
Property defines the alignment of flex items in the cross axis of a flexible box element.
<style>
#flex-container {
display: -webkit-box;
-webkit-box-align: center;
}
</style>
. . .
<div id="flex-container">
<!-- flex items -->
<div><img src="red-ball-small.png"/></div>
<div><img src="red-ball.png"/></div>
<div><img src="red-ball-small.png"/></div>
</div>
If the property had been set to start, left and right flex items would have been aligned with the start of the vertical cross axis:
The end value aligns flex items with the end of the flex container:
-webkit-box-direction
Property defines how flex items are placed in the flex container along the main axis. In the example below flex items are laid out in the reverse direction:
<style>
#flex-container {
display: -webkit-box;
-webkit-box-direction: reverse;
}
</style>
. . .
<div id="flex-container">
<!-- flex items -->
<div><img src="red-ball.png"/></div>
<div><img src="green-ball.png"/></div>
<div><img src="blue-ball.png"/></div>
</div>
-webkit-box-flex
Property specifies the flexibility of flex items: it allows them to be stretched or shrunk to fit the size of their flex container:
<style>
#flex-container {
display: -webkit-box;
}
#red-flex-item {
background-color: rgba(255, 0, 0, 0.5);
-webkit-box-flex: 1.0;
}
#green-flex-item {
background-color: rgba(0, 255, 0, 0.5);
-webkit-box-flex: 2.0;
}
#blue-flex-item {
background-color: rgba(0, 0, 255, 0.5);
-webkit-box-flex: 9.0;
}
</style>
. . .
<div id="flex-container">
<!-- flex items -->
<div id="red-flex-item"><img src="red-ball.png"/></div>
<div id="green-flex-item"><img src="green-ball.png"/></div>
<div id="blue-flex-item"><img src="blue-ball.png"/></div>
</div>
-webkit-box-flex-group
Property specifies the group number of a flexible element: any flexible boxes with the same group number are adjusted to be the same size.
-webkit-box-lines
Property arranges flex items as a single line or multiple lines.
-webkit-box-ordinal-group
Property indicates the ordinal group number of a flex item. Items with lower values are displayed first:
<style>
#flex-container {
display: -webkit-box;
}
#red-ball {
-webkit-box-ordinal-group: 3;
}
#green-ball {
-webkit-box-ordinal-group: 2;
}
#blue-ball {
-webkit-box-ordinal-group: 1;
}
</style>
. . .
<div id="flex-container">
<!-- flex items -->
<div><img src="red-ball.png"/></div>
<div><img src="green-ball.png"/></div>
<div><img src="blue-ball.png"/></div>
</div>
-webkit-box-orient
Property sets the orientation of flex items, thus defining the direction of the main axis.
-webkit-box-pack
Property specifies alignment of flex items along the main axis.