CSS3 Flexible Boxes (flexbox)
Webpage layouts haven't always been the most straight forward thing to code. Generally speaking, the more complex the layout, the greater the positional hacks needed in order to get your layout to behave the way you want it to.
Before flexbox came along there were four main layout modes used to determine the size and position of boxes on a page, based on their relationship with their child and parent boxes:
- The block layout - lays elements on a page vertically
- The inline layout - lays elements on a page horizontally
- The table layout - lays data in a tabular format
- The position layout - for explicitly positioning elements within the page
Flexbox is very similar to the block layout, although it lacks a lot of the properties that can be used in a block layout, such as columns and floats.
Despite this, flexbox has more flexibility (no pun intended) for distributing space and aligning content. It easily solves many layout issues that developers have had to hack around since the dawn of time (possible slight exaggeration). A good example of this is how easy it is to vertically center items with flexbox.
Using flexbox, you can also lay elements out inside a container in either directions: horizontal or vertical, called the flex directions; you’re not bound to just one direction as in other layout modes. This allows for the creation of more adaptive and responsive layouts that adapt to the layout changes on different screen sizes and orientations.
Last but not least, you can change the visual order of elements inside the container without affecting their actual order in the markup. This means that you can change the order in which certain items appear on the page, while preserving their order in the markup. This is useful for when you want to highlight certain items, such as a featured blog post, even if those items don’t come first in the markup.
TL;DR - Flexbox is a more efficient way (than traditional methods) to lay out, align and distribute space among items in a container, even when their size is unknown and/or dynamic.
Support
At the time of writing support for the Flexible Box Layout Module is pretty good. All major browsers support it with the exception of IE11 which has a few known issues.
IE8 does not support flexbox.
Resources
Some excellent resources for getting to grips with flexbox:
Tutorial games
Reference guides
- CSS Tricks - A guide to flexbox
- Codrops - Flexbox
- Creative Bloq - The web design's guide to flexbox
- Using CSS Flexible Boxes: Mozilla Developer Netwrork
Reference guide
- Designating a flex container
- Properties
- align-content
- align-items
- align-self
- flex-direction
- flex-flow
- flex-wrap
- justify-content
- order
- Properties ignored by flexbox
- Flex shorthand
Designating a flex container
To designate an element as a flex container, set the 'display' property as either:
flex
sets the flex container as a block-level elementinline-flex
sets the flex container as an inline-level element
This defines the element as a flex container and its immediate children become flex items.
A flexbox container has a main axis (horizontal) and a cross axis (vertical).
align-content
Aligns a flex container's lines within the flex container when there is extra space on the cross axis.
This property accepts the same values as justify-content
align-items
The 'align-items' property positions items along the cross axis (vertical) and accepts the following values:
flex-start
align items at the start of the container's cross axisflex-end
align items at the end of the container's cross axiscenter
align items in the center of the cross axis
align-self
To vertically position flex items use align-self
.
This property accepts the same values as align-items
.
This isn't the same as order
, which is how I first interpreted it. align-self
allows the flex items to be vertically aligned independently, whilst still maintaining their order.
As an example, four flex items in a default row are ordered 1, 2, 3, 4. But items 2 and 4 use align-self
to vertically position themselves at the bottom of the flex container.
flex-direction
The 'flex-direction' property specifies how flex items are placed in the flex container, by setting the direction of the flex container's main axis.
The initial value for the 'flex-direction' property is row
. With this value the flex container's main axis has the same orientation as the current writing mode. For the English language the writing mode is left-to-right, so the main axis will also run left-to-right.
By default the main axis is horizontal and the cross axis is vertical, but the 'flex-direction' property can manipulate the axis in different ways using the following values:
row
(initial value) lay out the main axis from left to rightrow-reverse
lay out the main axis from right to leftcolumn
lay out the main axis from top to bottom (the cross axis will now run left to right)column-reverse
lay out the main axis from bottom to top
flex-flow
The flex-direction
and flex-flow
properties are used so often together that flex-flow
was created as a shorthand property to combine them.
You can use one value from each property and separate them with a space. For example: flex-flow: row wrap
flex-wrap
The 'flex-wrap' property controls whether the flex container is single-line or multi-line with these accepted values:
nowrap
(initial value) every item is fit to a single linewrap
items wrap to additional lineswrap-reverse
items wrap to additional lines in reverse order
justify-content
The 'justify-content' property aligns flex items along the main axis (horizontal) and accepts the following values:
flex-start
(initial value) group items at the start of a container's main axisflex-end
group items at the end of a container's main axiscenter
group items in the center of the main axisspace-between
evenly distribute items along the main axis with the first item at the start of the axis and the last item at the very endspace-around
evenly distribute items along the main axis so that all items have equal space
order
The order
property defines the order in which an item appears in the flex container and can accept positive and negative integer values.
All flex items begin with a default order of 0, so an item with an order value greater than 0 will be positioned relative to items still set to the default.
#
position an item relative to the other items in the container
Properties ignored by flexbox
column-
properties of the multiple column module have no effect on a flex itemclear
has no effect on a flex itemfloat
causes thedisplay
property of the element to compute toblock
vertical-align
has no effect on the alignment of flex items
Flex shorthand
The flex
property specifies the three components of a flexible length: the flex grow factor, the flex shrink factor and the flex basis.
It is for use on flex items and tells the browser the size that the item should be in relation to the other flex items within the flex container.
flex: 1 0 auto;
- The first number specifies the flex-grow factor, which determines how much the flex item will grow relative to the rest of the flex items in the flex container
- The second number specifies the flex-shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container
- The final component specifies the flex basis, which is the initial main size of the flex item before free space is distributed.