CSS: making your pages look goodCreate account
Lesson 5 of 8

Flexbox

So far every element on your page has been stacked on top of each other. But most designs need things side by side: a logo next to a menu, three cards in a row, an icon next to some text. For a long time this was surprisingly hard to do in CSS. Then Flexbox arrived and made it easy.

Turning on Flexbox

Flexbox works on a parent element and its direct children. You turn it on by giving the parent display: flex:

html
<nav class="menu">
  <a href="#about">About</a>
  <a href="#learning">Learning</a>
  <a href="#contact">Contact</a>
</nav>
css
.menu {
  display: flex;
}

That's it. The links now sit in a row. The parent is called the flex container and the children are flex items. Everything else in this lesson is about controlling how those items are laid out.

Spacing items with gap

The easiest way to add space between flex items is gap:

css
.menu {
  display: flex;
  gap: 24px;
}

Unlike margins, gap only adds space between items, not before the first one or after the last one. That's almost always what you want.

Quick check

You add display: flex to a nav. Which elements end up side by side?

Select one answer

Row or column

By default, flex items go in a row. You can change that with flex-direction:

css
.stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

Now the items go top to bottom instead. That might sound like what happened without Flexbox, but you get gap and all the alignment tools that come next.

The direction you pick is called the main axis. The other direction is the cross axis. In a row, the main axis goes left to right and the cross axis goes top to bottom. In a column, it's the other way around. Keep that in mind, because the next two properties depend on it.

Aligning items

Two properties do most of the work:

  • justify-content positions items along the main axis
  • align-items positions items along the cross axis
css
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

With space-between, the first item goes to the start, the last item goes to the end and any others are spread out between them. That's the classic header: logo on the left, menu on the right. align-items: center lines them up vertically in the middle, even if one is taller than the other.

Other useful values for justify-content are flex-start (the default), center and flex-end. For align-items, try flex-start, center and stretch.

Quick check

You want a logo on the far left and a menu on the far right of a header. Which value do you use?

Select one answer

Centering anything

Remember how centering used to be hard? With Flexbox, centering something both horizontally and vertically is three lines:

css
.center-me {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 300px;
}

Whatever is inside ends up right in the middle. The min-height is there so the container has some height to center things in.

Wrapping onto new lines

By default, flex items squeeze onto a single line, even if they get very narrow. To let them wrap onto the next line when there isn't enough room, use flex-wrap:

css
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

This is perfect for things like a list of tags or skills, which should just flow onto as many lines as they need.

Growing to fill space

Sometimes you want an item to take up all the leftover space. Give it flex: 1:

css
.search {
  display: flex;
  gap: 8px;
}

.search input {
  flex: 1;
}

The input stretches to fill the row and the button next to it keeps its natural size.

Quick check

Flex items are getting squished onto one line on small screens. What helps?

Select one answer

A game to practice with

Flexbox clicks once you've played with it for a while. Flexbox Froggy (flexboxfroggy.com) is a free little game where you move frogs onto lily pads by writing Flexbox CSS. It takes about twenty minutes and it's genuinely fun.

Try it yourself

Use Flexbox on your website:

  1. Turn your header into a flex container with your name on the left and the menu on the right, using justify-content: space-between and align-items: center
  2. Make your nav list a flex container so the links sit in a row with a gap. Tip: remove the bullet points with list-style: none on the ul, and its default spacing with padding: 0
  3. If you have a list of interests or skills, show them as little tags that wrap with flex-wrap: wrap

Then play a few levels of Flexbox Froggy.