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.
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.
Some excellent resources for getting to grips with flexbox:
- CSS Tricks - A guide to flexbox
- Codrops - Flexbox
- Creative Bloq - The web design's guide to flexbox
- Using CSS Flexible Boxes: Mozilla Developer Netwrork
- Designating a flex container
- Properties ignored by flexbox
- Flex shorthand
Designating a flex container
To designate an element as a flex container, set the 'display' property as either:
flexsets the flex container as a block-level element
inline-flexsets 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).
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
The 'align-items' property positions items along the cross axis (vertical) and accepts the following values:
flex-startalign items at the start of the container's cross axis
flex-endalign items at the end of the container's cross axis
centeralign items in the center of the cross axis
To vertically position flex items use
This property accepts the same values as
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.
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 right
row-reverselay out the main axis from right to left
columnlay out the main axis from top to bottom (the cross axis will now run left to right)
column-reverselay out the main axis from bottom to top
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
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 line
wrapitems wrap to additional lines
wrap-reverseitems wrap to additional lines in reverse order
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 axis
flex-endgroup items at the end of a container's main axis
centergroup items in the center of the main axis
space-betweenevenly distribute items along the main axis with the first item at the start of the axis and the last item at the very end
space-aroundevenly distribute items along the main axis so that all items have equal space
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 item
clearhas no effect on a flex item
displayproperty of the element to compute to
vertical-alignhas no effect on the alignment of flex items
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.