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.
.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.
| Axis | Role | Property that aligns it |
|---|---|---|
| Main axis | Direction items follow one another in | justify-content |
| Cross axis | Perpendicular to the main axis | align-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.
.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-directionpicks the direction of the main axis, row or columnjustify-contentdistributes the available space along the main axisalign-itemsaligns items along the cross axisflex-wrapallows items to wrap onto a new line when space runs outgapspaces 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.
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
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.
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.
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.