Flexbox: laying things out in a row or a column

Why:Most menus, rows of cards and page headers today are built with flex. Afterwards you’ll be able to align items along both axes, share out the space, and build a menu that wraps on a narrow screen.

25 minutes

Read by speech synthesis (Qwen3-TTS); the voice is not a person’s.

Flexbox is a CSS layout mode that lines up the children of an element in a row or a column and shares out the space along a main axis and a cross axis.

A new era, a new layout

You’ve reached 2014. Most sites now open on phones, screen widths vary wildly, and float as a layout tool has worn everyone out. This is when browsers gain flexbox (the Flexible Box Layout). The first drafts of the specification date from 2009, and the final form you’ll use now settled around 2012 to 2014. It became common once every major browser supported it. For our practice that means no tables and no floating blocks: rows and columns line themselves up.

The container and its items

Flexbox works like this: you declare a parent to be a flex container, and its children become flex items, which line up in a row or a column.

.menu {
  display: flex;
  gap: 1rem;
}

Two lines, and the menu items stand in a row with space between them. Now two ideas that everything else rests on:

  • the main axis is the direction the items run in. By default it goes left to right (flex-direction: row). Say column, and it goes top to bottom;
  • the cross axis is perpendicular to the main one.

And two properties for the two axes: justify-content spreads items along the main axis, and align-items aligns them along the cross axis. When the direction changes, the axes swap places, and the properties swap jobs with them. That is the one thing people mix up here. Play with the diagram: change the direction and watch.

The main axis and the cross axis
flex-direction
justify-content (along the main axis)
align-items (along the cross axis)
.menu {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: stretch;
  flex-wrap: nowrap;
  gap: 8px;
}

The main axis runs left to right, and justify-content does its work along it. The cross axis is perpendicular to it, and align-items works along that one. Change flex-direction and the axes swap places, together with the properties that follow them.

Check yourself: what changes if flex-direction goes from row to column?

The main axis becomes vertical, so justify-content spreads items from top to bottom, and align-items aligns them horizontally.

Container properties

  • display: flex turns flexbox on;
  • flex-direction: row | column (and -reverse) says which way the items run;
  • flex-wrap: wrap lets items move to the next line. Without it everything stays on one line and, if there isn’t enough room, shrinks or spills past the edge;
  • justify-content: flex-start | center | flex-end | space-between | space-around spreads items along the main axis;
  • align-items: stretch | flex-start | center | flex-end aligns them on the cross axis. The default, stretch, makes items as tall as their row, which is why cards in one row have equal heights;
  • gap: 1rem is the space between items. It used to be done with margins, and you had to fight the extra margin after the last item. gap has worked for flexbox in all modern browsers since 2021.

Item properties

The main property of an item is flex, a shorthand for three values:

.card {
  flex: 1 1 14rem;
}

These are flex-grow (can it grow and take free space?), flex-shrink (can it shrink?) and flex-basis (the size it would like before growing or shrinking). flex: 1 1 14rem reads: “I want a width of 14rem, but I can grow to fill the row and I can shrink.” That is how you get cards that wrap onto the next line by themselves: four in a row on a wide screen, one on a phone, without a single line about the screen.

There is also align-self (align one item differently) and order (change the order). Be careful with the second: it changes only how things look, while the keyboard and screen reader order stays the same. Eyes and narrator part ways. It’s better to change the order of the items in the HTML itself.

Three ready-made tricks are worth remembering:

  • a header with the name on the left and the menu on the right: justify-content: space-between;
  • centering a block on both axes (a task once thought a joke): justify-content: center; align-items: center;
  • pushing one item to the right: margin-left: auto.
Check yourself: what does flex: 1 1 14rem do?

The item wants a width of 14rem, but it can grow to fill the free space and shrink if there isn’t enough.

Practice

A new era, a new page: in 2014 your site is built from scratch, but with no styling yet. Your styles.css already holds the base, what people in 2014 called a “reset”: sizes, fonts, colors. Your job is the layout.

Because every era is built from scratch, the stylesheet has to be linked again. It’s the same line as in 2005. After that you lay out the header, the menus, the main and side blocks and the cards with flexbox. Try the result yourself: drag the edge of the browser window and check that the menus and cards wrap instead of spilling over the edge.

What was wrong with 2014

The new layout was good, but it was still written in “desktop” sizes: widths in pixels, images with no fallback size. In the next lessons you’ll make it responsive. There was another catch: the first flexbox had two different syntaxes, and Internet Explorer 10 understood a third, so authors wrote every variant one after another. That habit left with those browsers.

Practice

Preparing your page…

Test

Question 1 of 6

Along which axis does justify-content work?

One answer

Cards

These cards go into your review once you finish the lesson.

  • What are the main axis and the cross axis in flexbox?

    Answer

    The main axis follows flex-direction (left to right by default), and the cross axis is perpendicular to it. justify-content works along the main axis, align-items along the cross axis.

  • Which properties does a flex container have?

    Answer

    display: flex, flex-direction, flex-wrap, justify-content, align-items and gap. They control how the children are laid out.

  • What does flex: 1 1 14rem mean?

    Answer

    flex-grow 1 (it can grow), flex-shrink 1 (it can shrink) and flex-basis 14rem (the width it wants). Together they make cards that wrap onto the next line by themselves.

  • When do you use flexbox, and when grid?

    Answer

    Flexbox for a single row or column (a menu, a header, a row of cards). Grid for rows and columns together (a page layout, a grid of cards).

Sources

Videos

Learn flexbox the easy way (Kevin Powell)

The video loads from youtube-nocookie.com only when you press play.

Open on the site

Next

You now know: Flexbox.