CSS Flexbox — The Basics
Build a real mental model of CSS Flexbox: turning an element into a flex container, the main and cross axes, distributing items with justify-content, aligning with align-items, changing direction, wrapping, and spacing with gap.
Introduction
CSS Flexbox — the flexible box layout — is a one-dimensional system for arranging elements along a single row or a single column. You opt in by turning an element into a flex container with display: flex; from that moment its direct children become flex *items*, and the browser takes over sizing and positioning them along one axis for you. It is the modern replacement for the float-and-clear and inline-block hacks that layouts once relied on.
Why does Flexbox exist? Before it, laying out a row of boxes, spreading them evenly, or vertically centering content meant floats, negative margins, and table tricks that broke the moment the content changed. Flexbox replaces that with a small vocabulary of properties that describe *intent* — space these out evenly, center these vertically — and lets the layout engine compute the pixels. Because it is content-aware, a flex layout adapts as items grow, shrink, or wrap onto new lines without hand-tuned widths.
The entire model rests on two axes. The main axis runs in the direction the container lays items out; the cross axis runs perpendicular to it. justify-content distributes items along the main axis, while align-items positions them on the cross axis. Hold that one pair in your head — main versus cross — and every flex property you meet afterward slots cleanly into one side or the other. That is the whole trick.
Lessons
1. Turning an element into a flex container
Everything starts with one declaration. Setting display: flex on an element makes it a flex container, and its *direct children* — and only its direct children — become flex items. The container establishes a layout context; the items are what get arranged inside it. Nothing deeper in the tree is affected unless you make those descendants flex containers too. This single line is the foundation the rest of the model builds on.
.container {
display: flex;
}
/* every direct child of .container is now a flex item */
2. The two axes: main and cross
A flex container has a main axis and a cross axis. By default items flow left-to-right, so the main axis is horizontal and the cross axis is vertical. This is the single most important idea in Flexbox: the axis-based properties do not mean left or top, they mean along the main axis or along the cross axis. Change the direction and the axes rotate with it, which is exactly why the same properties keep working when a layout switches from a row to a column.
.container {
display: flex;
/* main axis → horizontal, cross axis → vertical (defaults) */
}
3. Distributing items on the main axis with justify-content
Once you understand the main axis, justify-content follows immediately: it distributes items *along the main axis*. flex-start packs them at the start, center groups them in the middle, and the space keywords — space-between, space-around, space-evenly — spread the leftover room between items in different ways. This is the property you reach for to build a navigation bar, a toolbar, or any row where the spacing between items is what matters. See the full justify-content reference for every value.
.container {
display: flex;
justify-content: space-between;
}
4. Aligning items on the cross axis with align-items
Where justify-content works along the main axis, align-items positions items on the cross axis — vertically, in a default row. Its default is stretch, which is why flex items in a row grow to equal height automatically. Switch it to center and every item lines up on the vertical middle; flex-start and flex-end pin them to the top or bottom. This is the property that finally makes vertical centering trivial. The align-items reference documents each value in full.
.container {
display: flex;
align-items: center;
}
5. Direction and wrapping: flex-direction and flex-wrap
The flex-direction property chooses which way the main axis points: row (the default) lays items out horizontally, while column stacks them vertically and rotates both axes ninety degrees — now justify-content works vertically and align-items works horizontally. By default items never wrap; they shrink to fit one line. Set flex-wrap: wrap and items that no longer fit flow onto a new line instead, which is how a responsive card grid holds together as the viewport narrows.
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
6. Spacing items with gap
The gap property sets consistent space *between* flex items without adding margins to the items themselves. It applies only between items, never on the outer edges, which makes it far cleaner than the old margin-and-negative-margin dance. In a wrapping layout gap also controls the space between rows. Reach for gap first whenever you need even spacing in a flex row or column — it is the simplest tool in the whole model.
.container {
display: flex;
gap: 1rem;
}
That is the complete mental model. You make a container with display: flex; its direct children become items laid out along a main axis with a perpendicular cross axis; justify-content distributes on the main axis and align-items aligns on the cross axis; flex-direction rotates the axes and flex-wrap lets items flow onto new lines; and gap spaces them evenly. Every remaining flex property — flex-grow, order, align-self — is a refinement resting on that same frame.
Practice
Predict first: in a default flex row, which axis does align-items: center move items along — horizontal or vertical? (Answer: the cross axis, which is vertical, so it centers them top-to-bottom.) Now experiment for real — a flex row of numbered items you can rearrange:
Next steps
You have the model — now put it to work. Browse the runnable flexbox examples for copy-paste layouts, follow how to center a div for the most-searched flex task, or read the value-by-value references for justify-content and align-items. When your layout needs two dimensions at once — rows *and* columns together — step up to CSS Grid. Every snippet here runs in the editor.
Frequently asked questions
What is the difference between the main axis and the cross axis in Flexbox?
justify-content works along the main axis, align-items along the cross axis.How do I make an element a flex container?
display: flex on it. Its direct children then become flex items arranged along the main axis; descendants deeper in the tree are unaffected unless they are made flex containers too.What is the difference between justify-content and align-items?
justify-content distributes items along the main axis (spacing them in a row), while align-items positions items on the cross axis (aligning them, for example vertically centering a row).