Flexbox in CSS: the alignment system that ended layout hacks

Flexbox aligns items and distributes space inside a container along a single axis at a time, in a row or in a column.
5 min read
Believemy logo

Lining elements up side by side, centering them vertically, or spreading space evenly between them: these layout needs show up on almost every interface, a navigation bar, a list of cards, a form. For years, getting them right meant combining floats with approximate margin math. Flexbox was built to solve exactly this kind of arrangement.

It shows up anywhere elements need to line up in a row or a column in a predictable way, without knowing each item's exact size ahead of time. Understanding Flexbox mostly comes down to understanding two axes and a handful of properties that apply to them: the rest follows fairly naturally.


Definition

Flexbox, short for Flexible Box Layout, is a CSS layout system built to distribute space between the items inside a container, in a single direction at a time: in a row, or in a column. It gets switched on by setting an element's display property to flex. That element then becomes a flex container, and every one of its direct children automatically becomes a flex item, with no class needed on them at all.

CSS
.container {
  display: flex;
}

That single line already changes how the children behave: instead of stacking vertically by default, they line up in a row, side by side, across the container's full available width.


Two axes, not four sides

Flexbox's whole logic rests on two axes that get redefined depending on the chosen direction, rather than on the four fixed sides (top, bottom, left, right) used elsewhere in CSS. The main axis is the one items naturally line up along: by default, a horizontal line, running left to right. The cross axis runs perpendicular to it.

AxisRoleProperty that aligns it
Main axisDirection items follow one another injustify-content
Cross axisPerpendicular to the main axisalign-items

What throws people off the first time is that these two axes are not fixed: flex-direction can rotate the main axis from horizontal to vertical, and when it does, justify-content and align-items swap roles without a single character of their own syntax changing.


A concrete example

A typical navigation bar shows off what Flexbox is good for: a logo on the left, links on the right, everything centered vertically, without a single hand-calculated margin.

CSS
.nav-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

Four lines do the job: the first switches on Flexbox, the second pushes the logo and the links toward opposite edges, the third centers everything vertically regardless of the logo's or the menu's actual height, and the last simply adds breathing room around it all.


What Flexbox does not do

Flexbox thinks in one dimension at a time, a row or a column. Once a layout needs to control rows and columns at once, like a two-dimensional grid of products, a dedicated grid system becomes the better tool. The two complement each other far more than they compete: Flexbox for aligning the contents of a bar or a card, a grid for structuring the whole page around fixed zones.


The properties worth knowing

Once display: flex is set, everything else plays out through a handful of companion properties, each in charge of one precise aspect of the arrangement.

  • flex-direction picks the direction of the main axis, row or column
  • justify-content distributes the available space along the main axis
  • align-items aligns items along the cross axis
  • flex-wrap allows items to wrap onto a new line when space runs out
  • gap spaces items apart without a single margin to manage


The starting pitfall

The most common mistake is setting display: flex on a container, then being surprised when items overflow or get squeezed on a small screen. By default, Flexbox never wraps items onto a new line: they all get compressed onto a single line, no matter how narrow it is. Our HTML and CSS course has learners see that overflow on mobile before adding flex-wrap, so the need for that line becomes obvious instead of memorized.

Good to knowOn any layout meant to adapt to several screen widths, add flex-wrap: wrap from the start. Without that line, a responsive flex container will almost always overflow on mobile instead of settling onto several lines.


Frequently asked questions

QuestionShould Flexbox always be preferred over a CSS grid?

No, it depends on how many dimensions need controlling. Flexbox is a great fit for one-dimensional alignment, like a toolbar or a row of buttons. Once a layout has to align content in rows and columns at the same time, like a photo grid, a dedicated grid system ends up simpler to write and to maintain.

QuestionWhy do my flex items not fill the container's full height?

Because the cross-axis alignment property defaults to stretch, which should stretch them in the first place. The block almost always comes from somewhere else: a flex item with an explicit height set in CSS ignores that behavior, or the container itself has no defined height, in which case there is nothing to stretch toward.

QuestionDoes display: flex also change how grandchildren behave?

No, only the container's direct children become flex items. The children of those children keep their usual display behavior, unless display: flex gets applied to their own container too. That scope, limited to direct children, keeps a single change from spreading uncontrolled through a whole tree of elements.

Related terms

Discover our hTML and CSS glossary

Browse the terms and definitions most commonly used in HTML and CSS development.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.