Understanding and Using Flexbox in CSS

Hero image for Understanding and Using Flexbox in CSS. Image by Singh.
Hero image for 'Understanding and Using Flexbox in CSS.' Image by Singh.

Flexbox, or the 'Flexible Box Layout' as it is formally known, is a CSS3 layout model that allows items within a container to be distributed and aligned in a predictable manner, even with unknown sizes or dynamic content. This makes it an invaluable tool for modern web design, where responsiveness and fluid layouts are key. Whether you're a budding web developer or a designer looking to strengthen your CSS skills, understanding Flexbox is crucial.


What is Flexbox?

Essentially, Flexbox is a onedimensional layout method for laying out items in rows or columns. It enables space distribution and alignment of items in a complex layout, even when their size is unknown or dynamic.

Unlike traditional models, Flexbox lays out its items in a single dimension at a time. This means it can be either a row or a column, but not both at once, making it more straightforward and more predictable to work with.


Basic Concepts

Flex Container

The first step in using Flexbox is to define a flex container. This is done by setting an element's display property to flex or inlineflex.

.container {  display: flex;}

Flex Items

Once you have a flex container, all of that element's direct children become flex items. They automatically take on certain flex behaviours (which we will get to in a minute).

Main Axis and Cross Axis

The main axis is the primary direction in which flex items are placed in the flex container, while the cross axis is perpendicular to it. The direction of the main axis depends on the flexdirection property. Basically, sidetoside (row), or upanddown (column). row is the default value.

.container {  display: flex;  flex-direction: row; /* default value */}

Aligning and Distributing Space

justifycontent

This property defines how space is distributed between and around content items along the main axis. For example:

.container {  justify-content: space-between;}

Common values here include:

  • flexstart (this is the default): items are positioned toward the start (right or top, depending on direction);
  • flexend: the exact opposite of flexstart;
  • center: items are positioned in the middle;
  • spacebetween: items are distributed with equal space between them, with the first item and last items on the edges of the container.

alignitems

This property defines the default behaviour for how flex items are laid out along the crossaxis on the current line: the same as above, but in the opposite direction.

.container {  align-items: center;}

alignself

This property is used on the item rather than the container and allows the default alignment to be overridden for individual flex items.

.item {  align-self: auto | flex-start | flex-end | center | baseline | stretch;}

Flexibility of Flex Items

flexgrow

This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion:

.item {  flex-grow: 2; /* default 0 */}

flexshrink

This defines the ability for a flex item to shrink if necessary.

.item {  flex-shrink: 3; /* default 1 */}

flexbasis

This defines the default size of an element before the remaining space is distributed.

.item {  flex-basis: auto | 0 | <length>;}

The flex shorthand

If you want your CSS to feel more concise, then there is the option to use flex, which is shorthand for flexgrow, flexshrink and flexbasis combined. The second and third parameters (flexshrink and flexbasis) are optional. It looks something like this:

.item {  flex: 1 1 auto;}

Using gap in Flexbox

The gap property, a valuable feature mainly inherited from CSS Grid, is also available in Flexbox to provide some more control over how your flex items are spaced.

It behaves in exactly the same way it does when used with grid, specifying the size of the space between your items, and offering a clean and easy way to maintain a uniform gap in your layout.

For example:

.container {  display: flex;  gap: 1rem;}

Here, a 1rem gap will be added between each direct child of .container. I should note that you can use any unit of measurement here, including px and %.

An Important Note on Device Support

Whilst support for Flexbox has been extremely good for a long time, there are some nuances in that support when it comes to combining it with gap, which I've found has caught out even the most seasoned of frontend developers.

Specifically, Safari on iOS 14 and lower (13, 12, etc) does not support gap when used with flex at all. Considering iOS 15 was only released in September 2021 (and wasn't at all when this article was first put together), that means that there are a lot of user devices out there that will make a real mess of your layout if you aren't careful.

There's no real workaround for this short of using complex @supports queries and forcing margins onto the child items so it's something I personally avoid wherever possible.


Categories:

  1. CSS
  2. Front‑End Development
  3. Responsive Development