CSS Flexbox

Line things up in rows or columns, space them out and centre anything.

Lesson 19 of 49Intermediate16 min read

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

CSS
.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 for row (the default), and top to bottom for column.
  • The cross axis runs at right angles to it.

You only need to remember two alignment properties:

  • justify-content positions items along the main axis.
  • align-items positions 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

PropertyCommon values
flex-directionrow, column, row-reverse
justify-contentflex-start, center, flex-end, space-between, space-around, space-evenly
align-itemsstretch (default), center, flex-start, flex-end, baseline
flex-wrapnowrap (default), wrap
gap1rem, 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

PropertyWhat it does
flex-growHow much an item grows to fill spare space (1 means take a share)
flex-shrinkHow much it shrinks when there isn't enough space (0 means never)
flex-basisIts starting size before growing or shrinking
flexShorthand: flex: 1 grows items equally, flex: 0 0 200px fixes an item at 200px
align-selfOverrides align-items for one item
orderChanges 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: flex on a parent turns its direct children into flex items.
  • justify-content aligns items on the main axis; align-items on the cross axis.
  • flex-direction: column swaps the two axes.
  • Use gap for spacing and flex-wrap: wrap to let items move onto new lines.
  • flex: 1 makes 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.

Example 1

A navigation bar

Change space-between to center, flex-end or space-evenly and run.

.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; }
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 2The nav becomes a flex container; its 3 children line up in a row.
  2. Line 3Push the first and last item to the edges, with the rest spread between.
  3. Line 4Vertically centre everything, whatever their heights.
  4. Lines 11 to 14A flex container inside a flex item. Nesting like this is normal, and gap spaces the links.
Example 2

Centre anything

The famous "how do I centre a div?" question, answered in three lines.

.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;
}
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Lines 2 to 4Centre on the main axis (horizontal) and the cross axis (vertical).
  2. Line 5The container needs some height for vertical centring to be visible.
Example 3

Growing, wrapping cards

Make the result narrower (open in the playground and use the phone button): the cards wrap onto new lines.

.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;
}
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 3Items move to a new line when there isn't room.
  2. Line 8flex: 1 1 140px starts each card at 140px, then lets it grow and shrink as needed.
  3. Line 17The featured card takes twice as much of the spare space.
Example 4

Column direction

.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; }
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 3Stack items vertically.
  2. Line 15margin-top: auto in 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

Don't
.item { display: flex; justify-content: center; }
/* the items themselves don't move */
Do
.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

Don't
.item { margin-right: 16px; }
/* leaves an extra gap after the last item */
Do
.container { display: flex; gap: 16px; }

Mixing up the axes in a column

Don't
.col { display: flex; flex-direction: column; justify-content: center; }
/* "why isn't it centred horizontally?" */
Do
.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.

Fill in the blankseasy

Lay out the children in a row with space between them, vertically centred.

.toolbar {
  display: ;
  justify-content: ;
  align-items: ;
}
Multiple choicemedium

In a default flex row, which property centres items vertically?

Multiple choicemedium

What does flex: 1 on every item do?

Predict the outputmedium

How are the three boxes arranged?

.row { display: flex; flex-direction: column; justify-content: flex-end; height: 300px; }
Fix the bugmedium

The three buttons should sit in a row, 10px apart, and be centred horizontally inside the toolbar. Fix the CSS.

.toolbar button {
  display: flex;
  justify-content: center;
  margin: 10px;
}

.toolbar {
  padding: 10px;
  background: #e5e7eb;
}
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • 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.

  1. Which property turns on Flexbox?

    • flex: on
    • layout: flex
    • position: flex
    • display: flex
  2. What does flex-wrap: wrap allow?

    • 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
  3. Which justify-content value puts equal space between items but none at the edges?

    • space-between
    • space-around
    • space-evenly
    • center
  4. In a flex column, how do you push the last item to the bottom?

    • position: bottom
    • align-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.

  1. .comment is a flex container with a gap of 12px
  2. Items are aligned to the top (align-items: flex-start)
  3. The avatar never shrinks (flex-shrink: 0)
  4. .body grows to fill the remaining space (flex: 1)
.avatar { border-radius: 50%; }
.body p { margin: 4px 0 0; }
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • Comment is a flex container
  • 12px gap
  • Aligned to the top
  • Avatar doesn't shrink
  • Body grows
  • Avatar is left of the body