What you'll learn
- Lay out a nav bar and cards with flexbox
- Explain the main axis and cross axis and which property aligns along each
- Space flex items with gap instead of margins
- Make a card row wrap responsively with flex-wrap and the flex shorthand
Lay out a navigation bar and a row of cards with Flexbox: direction, alignment, gap and wrapping.
Why this matters
Before Flexbox, putting three boxes side by side and centring them vertically took floats, clearfix hacks and guesswork. Flexbox makes one-dimensional layout (a row or a column of items) simple and predictable. Navigation bars, toolbars, card rows, button groups and "centre this thing" are all Flexbox jobs you will meet every week.
The core idea: a container and its items
You turn an element into a flex containerAn element with display: flex; its direct children are laid out as flex items in a row or column. with one declaration. Its direct children become flex items:
.nav-list {
display: flex;
}<ul class="nav-list">
<li><a href="#routes">Routes</a></li>
<li><a href="#events">Events</a></li>
<li><a href="#join">Join</a></li>
</ul>The three list items now sit in a row. Only the direct children are affected; the links inside the items are laid out normally.
Two axes
A flex container has a main axisThe direction flex items flow in, horizontal for row and vertical for column, along which justify-content aligns. and a cross axisThe axis at right angles to the main axis, along which align-items aligns flex items..
flex-direction: row(the default) makes the main axis horizontal.flex-direction: columnmakes the main axis vertical.
Alignment properties are named after the axes, not after left/right or top/bottom, which is why they swap meaning when you change direction:
| Property | Set on | Works along | Common values |
|---|---|---|---|
justify-content | container | main axis | flex-start, center, space-between, flex-end |
align-items | container | cross axis | stretch (default), center, flex-start, flex-end |
gap | container | between items | 1rem, 0.5rem 1rem |
flex-wrap | container | lines | nowrap (default), wrap |
Worked example 1: a header bar
Logo on the left, navigation on the right, both centred vertically:
.site-header {
display: flex;
justify-content: space-between; /* push the two children apart */
align-items: center; /* centre them vertically */
}
.nav-list {
display: flex;
gap: 1rem; /* space between links, none at the ends */
list-style: none; /* remove the bullets */
margin: 0;
padding: 0;
}Flexbox containers can be nested: the header is a flex container whose second child (the nav's list) is a flex container itself.
gap is the modern way to space items. It puts space only between items, so you no longer need margins that leave an awkward extra gapA container property that adds space only between items, never at the ends. at the end.
Worked example 2: cards that wrap
.cards {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.card {
flex: 1 1 200px;
}flex: 1 1 200px is shorthand for three item properties:
flex-grow: 1: if there is spare space, take a share of it.flex-shrink: 1: if space is tight, you may shrink.flex-basis: 200px: start from a width of about 200px before growing or shrinking.
With flex-wrap: wrap, cards that do not fit move to the next line, and each line's cards grow to fill it. On a wide screen you get three cards in a row; on a phone, one per row. No media query needed.
Centring anything
The classic "centre a box both ways" problem becomes:
.hero {
display: flex;
justify-content: center;
align-items: center;
min-height: 60vh;
}Ordering, and why to be careful
order and flex-direction: row-reverse change the visual order without changing the HTML. Keyboard focus and screen readers still follow the HTML order, so a visual order that differs from the source confuses keyboard users. Change the HTML order instead whenever you can.
Common mistakes
- Putting
display: flexon the item instead of the parent. - Expecting grandchildren to be flex items. Only direct children are.
- Mixing up the axes after switching to
flex-direction: column(nowjustify-contentis vertical). - Forgetting
flex-wrap: wrap, so items squash or overflow instead of wrapping. - Using margins for spacing where
gapwould be simpler.
Quick recap
display: flexon the parent; direct children become flex items.justify-contentaligns along the main axis,align-itemsacross it;gapspaces items.flex-wrap: wrapplusflex: 1 1 <basis>gives responsive card rows.- Keep the HTML order and the visual order the same.
Try it
Open the Do tab and use Flexbox to turn a stacked header and cards into a proper nav bar and a wrapping card row.
Key terms (5)
- flex container
- An element with display: flex; its direct children are laid out as flex items in a row or column.
- main axis
- The direction flex items flow in, horizontal for row and vertical for column, along which justify-content aligns.
- cross axis
- The axis at right angles to the main axis, along which align-items aligns flex items.
- gap
- A container property that adds space only between items, never at the ends.
- flex-basis
- The starting size of a flex item before it grows or shrinks to share the available space.