Understanding and Using Flexbox in CSS

Abstract image used to represent Understanding and Using Flexbox in CSS
Image by Singh.

Flexible Box Layout, or Flexbox, is usually my first choice when a set of items needs to align or distribute space along one axis. The container can control direction, wrapping, alignment, and the way spare space is shared without pretending the content has fixed dimensions. When rows and columns need to coordinate together, Grid is normally the better model.


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 inline-flex.

.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 follows flex-direction, and the cross axis is perpendicular to it. row, the default, follows the inline axis; column follows the block axis. Their physical direction depends on the writing mode and text direction, so a row is not always horizontal.

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

Aligning and Distributing Space

justify-content

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:

  • flex-start (this is the default): items are positioned towards the mainstart edge. For a lefttoright row that is the left edge; reversing the row or changing writing direction changes which physical edge is the start;
  • flex-end: the exact opposite of flex-start;
  • center: items are positioned in the middle;
  • space-between: items are distributed with equal space between them, with the first item and last items on the edges of the container.

align-items

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;
}

align-self

align-self lets an individual item override the container's default crossaxis alignment. Choose one value, such as flex-start below; alternatives include auto, flex-end, center, baseline and stretch.

.item {
  align-self: flex-start;
}

Flexibility of Flex Items

flex-grow

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 */
}

flex-shrink

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

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

flex-basis

flex-basis supplies the item's initial main size before free space is distributed. Choose one value: auto, 0, or a length such as 12rem, depending on the layout. This example uses auto:

.item {
  flex-basis: auto;
}

The flex shorthand

If you want your CSS to feel more concise, then there is the option to use flex, which is shorthand for flex-grow, flex-shrink and flex-basis combined. The second and third parameters (flex-shrink and flex-basis) 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.

For a definite length such as 1rem, gap provides gutters between items and flex lines much as it does between grid tracks. Percentage gaps need more care: when the relevant container size is indefinite, Flexbox and Grid can resolve them differently. A cyclic percentage gap resolves to zero in Flexbox, whilst Grid can apply it after intrinsic sizing and produce overflow.

For example:

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

Here, gap: 1rem spaces the flex items. Lengths such as px and rem are straightforward choices; if you use %, check the container's dimensions and the resulting layout rather than assuming it behaves exactly like Grid.

An Important Note on Device Support

Flexbox itself has broad support, but older browsers may still lack gap in flex layouts. Check the actual browser versions the project needs to support.

Safari before 14.1 and iOS/iPadOS before 14.5 do not support gap in flex layouts. Those older versions can still matter for a December 2021 project, so a gaponly layout needs checking against its intended devices.

At the time, the practical fallback was to space flex items with margins. An @supports query could not distinguish gap support in Grid from gap support in Flexbox, so it could not select that fallback reliably on its own.


Need a senior engineer involved?

I can work directly in the codebase, review the architecture, or support the team through delivery when the work needs more than extra hands.