Flexbox is the CSS layout tool for arranging items in one direction, either a row or a column. Navigation bars, button groups, rows of cards and perfectly centred content are all a few lines of Flexbox.
Before Flexbox, developers used floats and positioning tricks for these layouts, and something as simple as centring an element vertically was a well-known headache. Flexbox handles spacing, alignment and wrapping for you, and it adapts to the size of the content and the screen.
Flexbox works with two roles: the flex container (the parent) and the flex items (its direct children). Almost every property belongs to one role or the other, and mixing them up is the most common Flexbox mistake.
Turning on Flexbox with display: flex
.container { display: flex; }As soon as you add this, the children of .container line up in a row, side by side. Everything else in this lesson is about controlling that row: which direction it runs, how the space is shared, and how items line up.
Only the direct children become flex items. Grandchildren keep behaving normally unless their own parent is also a flex container.
Main axis and cross axis
- The main axis runs in the direction set by
flex-direction: left to right forrow(the default), and top to bottom forcolumn. - The cross axis runs at right angles to it.
You only need to remember two alignment properties:
justify-contentpositions items along the main axis.align-itemspositions items along the cross axis.
When flex-direction: column is set, the axes swap, so justify-content becomes vertical and align-items becomes horizontal.
Flex container properties
| Property | Common values |
|---|---|
flex-direction | row, column, row-reverse |
justify-content | flex-start, center, flex-end, space-between, space-around, space-evenly |
align-items | stretch (default), center, flex-start, flex-end, baseline |
flex-wrap | nowrap (default), wrap |
gap | 1rem, the space between items |
By default, items try to stay on one line and shrink to fit. Add flex-wrap: wrap when you want them to move onto a new line instead, as in a row of cards on a narrow screen.
Flex item properties
| Property | What it does |
|---|---|
flex-grow | How much an item grows to fill spare space (1 means take a share) |
flex-shrink | How much it shrinks when there isn't enough space (0 means never) |
flex-basis | Its starting size before growing or shrinking |
flex | Shorthand: flex: 1 grows items equally, flex: 0 0 200px fixes an item at 200px |
align-self | Overrides align-items for one item |
order | Changes the visual order (use carefully, because screen readers follow the HTML order) |
CSS Flexbox Syntax
Flexbox essentials
.container {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 1rem;
}
.item { flex: 1; }CSS Flexbox Summary
display: flexon a parent turns its direct children into flex items.justify-contentaligns items on the main axis;align-itemson the cross axis.flex-direction: columnswaps the two axes.- Use
gapfor spacing andflex-wrap: wrapto let items move onto new lines. flex: 1makes items share the available space equally.
CSS Flexbox Examples
Each example runs in the page. Edit the code and press Run to see what changes.
A navigation bar
Change space-between to center, flex-end or space-evenly and run.
<nav class="nav">
<a class="logo" href="#">Bloom</a>
<div class="links">
<a href="#">Learn</a>
<a href="#">Practice</a>
<a href="#">Blog</a>
</div>
<a class="cta" href="#">Get started</a>
</nav>.nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
background: #15161b;
border-radius: 14px;
font-family: sans-serif;
}
.links {
display: flex;
gap: 16px;
}
.nav a { color: white; text-decoration: none; }
.logo { font-weight: 800; }
.cta { background: #ffd23f; color: #15161b !important; padding: 6px 14px; border-radius: 99px; }Line-by-line explanation
- Line 2The nav becomes a flex container; its 3 children line up in a row.
- Line 3Push the first and last item to the edges, with the rest spread between.
- Line 4Vertically centre everything, whatever their heights.
- Lines 11 to 14A flex container inside a flex item. Nesting like this is normal, and
gapspaces the links.
Centre anything
The famous "how do I centre a div?" question, answered in three lines.
<div class="stage">
<div class="box">Perfectly centred</div>
</div>.stage {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
background: #e1e6ff;
border-radius: 14px;
}
.box {
padding: 14px 20px;
background: white;
border: 2px solid #4467ff;
border-radius: 10px;
}Line-by-line explanation
- Lines 2 to 4Centre on the main axis (horizontal) and the cross axis (vertical).
- Line 5The container needs some height for vertical centring to be visible.
Growing, wrapping cards
Make the result narrower (open in the playground and use the phone button): the cards wrap onto new lines.
<div class="cards">
<article class="card">Basic</article>
<article class="card">Pro</article>
<article class="card featured">Team</article>
</div>.cards {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.card {
flex: 1 1 140px;
padding: 24px;
background: #fff1c2;
border: 2px solid #15161b;
border-radius: 12px;
font: 700 18px sans-serif;
}
.featured {
flex-grow: 2;
background: #d6f4e4;
}Line-by-line explanation
- Line 3Items move to a new line when there isn't room.
- Line 8
flex: 1 1 140pxstarts each card at 140px, then lets it grow and shrink as needed. - Line 17The featured card takes twice as much of the spare space.
Column direction
<aside class="sidebar">
<a href="#">Dashboard</a>
<a href="#">Projects</a>
<a href="#">Settings</a>
<a href="#" class="logout">Log out</a>
</aside>.sidebar {
display: flex;
flex-direction: column;
gap: 6px;
height: 220px;
width: 160px;
padding: 12px;
background: #15161b;
border-radius: 12px;
}
.sidebar a { color: white; text-decoration: none; padding: 6px 8px; border-radius: 6px; }
.sidebar a:hover { background: #333845; }
.logout { margin-top: auto; color: #ff8f6b !important; }Line-by-line explanation
- Line 3Stack items vertically.
- Line 15
margin-top: autoin a flex column pushes this item to the bottom. It's a very handy trick.
Common CSS Flexbox Mistakes
Putting flex properties on the wrong element
.item { display: flex; justify-content: center; }
/* the items themselves don't move */.container { display: flex; justify-content: center; }display: flex and justify-content go on the parent. Only direct children become flex items.
Using margins for spacing between items
.item { margin-right: 16px; }
/* leaves an extra gap after the last item */.container { display: flex; gap: 16px; }Mixing up the axes in a column
.col { display: flex; flex-direction: column; justify-content: center; }
/* "why isn't it centred horizontally?" */.col { display: flex; flex-direction: column; align-items: center; }In a column, the main axis is vertical, so horizontal centring is align-items.
CSS Flexbox in Real Projects
Flexbox in the wild
Headers and navigation bars, button groups, form rows (label, input and button), media objects (an avatar beside text), footers with columns, and sidebars that push the last item to the bottom are all Flexbox. The header of this site is a flex container with gap, and margin-left: auto pushes the tools to the right.
CSS Flexbox Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Lay out the children in a row with space between them, vertically centred.
.toolbar {
display: ;
justify-content: ;
align-items: ;
}
display: flex, then justify on the main axis and align on the cross axis.In a default flex row, which property centres items vertically?
align-items.What does flex: 1 on every item do?
How are the three boxes arranged?
.row { display: flex; flex-direction: column; justify-content: flex-end; height: 300px; }
flex-end means the bottom.The three buttons should sit in a row, 10px apart, and be centred horizontally inside the toolbar. Fix the CSS.
<div class="toolbar">
<button>Bold</button>
<button>Italic</button>
<button>Link</button>
</div>.toolbar button {
display: flex;
justify-content: center;
margin: 10px;
}
.toolbar {
padding: 10px;
background: #e5e7eb;
}- Toolbar is a flex container
- Items are centred
- Buttons are 10px apart
- Buttons share one row
CSS Flexbox Quiz
4 questions to check what you learned.
Which property turns on Flexbox?
- flex: on
- layout: flex
- position: flex
- display: flex
What does
flex-wrap: wrapallow?- Text to wrap inside items
- Items to overlap
- Items to move onto new lines when there isn't room
- Wrapping the container in a border
Which
justify-contentvalue puts equal space between items but none at the edges?- space-between
- space-around
- space-evenly
- center
In a flex column, how do you push the last item to the bottom?
position: bottomalign-self: bottom- Give it
margin-top: auto order: -1
CSS Flexbox Challenge
Build a media object
Lay out a comment: avatar on the left, text on the right.
.commentis a flex container with agapof12px- Items are aligned to the top (
align-items: flex-start) - The avatar never shrinks (
flex-shrink: 0) .bodygrows to fill the remaining space (flex: 1)
<div class="comment">
<img class="avatar" src="https://picsum.photos/id/177/56/56" alt="Lee's avatar" width="56" height="56">
<div class="body">
<strong>Lee</strong>
<p>Flexbox finally clicked for me today. The axis thing is everything!</p>
</div>
</div>.avatar { border-radius: 50%; }
.body p { margin: 4px 0 0; }
- Comment is a flex container
- 12px gap
- Aligned to the top
- Avatar doesn't shrink
- Body grows
- Avatar is left of the body