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.