float or display: inline-block
trying to line elements up, Flexbox is the fix. This guide covers everything you need to lay out real interfaces.
What Problem Flexbox Solves
Before Flexbox, centering something vertically on a web page was famously awkward, developers joked about it for years. CSS was originally designed for documents, flowing text down a page, not for building app-like interfaces with navbars, cards, and sidebars. Flexbox was introduced specifically to make one-dimensional layout, arranging items in a row or a column, simple and predictable.
"One-dimensional" is the key idea. Flexbox is excellent at distributing space along a single line, either horizontally or vertically. When you need two-dimensional control, rows and columns at the same time, CSS Grid is the better tool, which we cover in a separate guide. Most navbars, button groups, and card rows are Flexbox jobs.
Turning a Container Into a Flexbox
Flexbox has two sides: the container (the parent) and the items (its direct children). You activate Flexbox on the container with a single line:
.container {
display: flex;
}
The moment you add display: flex, every direct child of that element
becomes a flex item, they instantly line up in a row, left to right, without you writing anything else.
That single property replaces dozens of lines of old-school layout hacks.
The Two Axes: Main and Cross
Flexbox thinks in terms of two axes. The main axis runs in the direction items are placed, by default left to right. The cross axis runs perpendicular to it, by default top to bottom. Almost every Flexbox property either controls spacing along the main axis or alignment along the cross axis, so understanding this distinction makes the rest of Flexbox click into place.
.container {
display: flex;
flex-direction: row; /* default: main axis is horizontal */
/* flex-direction: column; would make the main axis vertical */
}
Aligning Items Along the Main Axis
The justify-content property controls how items are spaced along the main
axis. This is what you reach for when you want items pushed apart, centered, or bunched together
horizontally (assuming the default row direction).
.navbar {
display: flex;
justify-content: space-between; /* logo on the left, links on the right */
align-items: center; /* vertically centers everything */
}
Common values you will use constantly:
flex-start— items bunch at the start (the default).center— items bunch in the middle.space-between— first and last items touch the edges, gaps distributed evenly between the rest.space-around— equal space around every item, including the edges.space-evenly— perfectly equal gaps everywhere, including edges.
Aligning Items Along the Cross Axis
align-items is the cross-axis equivalent, it controls vertical position
when the main axis is horizontal. This single property is how you finally center something vertically
without any tricks.
.hero {
display: flex;
justify-content: center; /* center horizontally */
align-items: center; /* center vertically */
height: 100vh;
}
The classic centering trick: display: flex; justify-content: center; align-items: center;
on a full-height container is the single most copied three-line snippet in modern CSS.
Controlling Individual Items
Some properties apply to the flex items themselves rather than the container. The most important is
flex, a shorthand controlling how an item grows or shrinks to fill
available space.
<div class="cards">
<div class="card">Card One</div>
<div class="card">Card Two</div>
<div class="card">Card Three</div>
</div>
<style>
.cards {
display: flex;
gap: 1rem;
}
.card {
flex: 1; /* each card grows equally to fill the row */
background: #f4f4f4;
padding: 1.5rem;
border-radius: 8px;
}
</style>
flex: 1 is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0;.
In plain terms, it tells the browser "this item can grow, can shrink, and starts from zero width, so
distribute the row equally." Change one card to flex: 2 and it takes up
twice as much space as its siblings.
Wrapping Items Onto Multiple Lines
By default, Flexbox tries to cram every item onto a single line, shrinking them if needed. For a row of
cards that should reflow on smaller screens, add flex-wrap:
.cards {
display: flex;
flex-wrap: wrap;
gap: 1.25rem;
}
.card {
flex: 1 1 260px; /* grow, shrink, but never smaller than 260px */
}
This pattern, flex: 1 1 260px combined with flex-wrap: wrap,
is how most responsive card grids are built without a single media query. As the screen shrinks, cards
simply drop to the next line once they can no longer fit at 260px wide.
A Complete Real-World Example: A Navbar
Let us build an actual responsive-ready navbar using everything above.
<nav class="navbar">
<div class="logo">BrandName</div>
<ul class="nav-links">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
.nav-links {
display: flex;
gap: 1.5rem;
list-style: none;
}
Two Flexbox containers, one nested inside the other. The outer .navbar
spreads the logo and link list apart with space-between. The inner
.nav-links lines the individual links up in a row with consistent
gap. This is the real pattern behind most navbars you see today,
including this very page.
Where to Go From Here
Flexbox handles rows and columns beautifully, but once your layout needs to control both dimensions at once, a full page grid with sidebars and headers, CSS Grid becomes the right tool. Read our CSS Grid guide next to complete your layout toolkit.
Ready to go beyond one tutorial?
This lesson is one piece of the full CodeVent Digital frontend curriculum. Start free and build real projects step by step.
Start Learning Free