Understanding and Using Flexbox in CSS

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 one‑dimensional 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 is the primary direction in which flex items are placed in the flex container, whilst the cross axis is perpendicular to it. The direction of the main axis depends on the flex-direction property. Basically, side‑to‑side (row), or up‑and‑down (column). row is the default value.
.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 main‑start edge. For a left‑to‑right 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 offlex-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 cross‑axis on the current line: the same as above, but in the opposite direction.
.container { align-items: center;}align-self
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
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
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 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.
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 front‑end developers.
Historical support note: when this article was first put together, Safari before 14.1 and iOS/iPadOS before 14.5 did not support gap in flex layouts, so a gap‑only layout could fail on devices still in use at the time. Flex‑gap support has since become widespread; check the browser range for the project rather than treating that historical warning as a permanent platform rule.
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.