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


Reference guide


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 element
  • inline-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 axis
  • flex-end align items at the end of the container's cross axis
  • center 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 right
  • row-reverse lay out the main axis from right to left
  • column 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 line
  • wrap items wrap to additional lines
  • wrap-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 axis
  • flex-end group items at the end of a container's main axis
  • center group items in the center of the main axis
  • space-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 end
  • space-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 item
  • clear has no effect on a flex item
  • float causes the display property of the element to compute to block
  • 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.

Like this post? Got a question?

Reply via Bluesky or Email.