Flexbox

Align flex items

Position items along the main and cross axes with justify-content, align-items, align-self, and gap.

Alignment in Flexbox comes down to two properties. justify-content moves items along the main axis. align-items moves them along the cross axis. Once you know which axis is which, the rest follows.

A hero section with a title on the left and a button on the right, both vertically centered:

.hero {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 2rem;
}

With the default flex-direction: row, space-between pushes the first item to the start and the last to the end, and center lines them up in the middle vertically. Switch to column and everything rotates: space-between now works top to bottom, and center works left to right.

justify-content needs free space

justify-content distributes the space left over after the items are sized. If there is no free space, it has nothing to distribute.

This is the most common “Flexbox is broken” moment. You set justify-content: space-between, nothing moves, and the reason is that one item has flex: 1 and already ate all the room. Check the item sizes first, then the alignment.

align-items and align-self

align-items defaults to stretch, so items without a fixed height grow to the tallest one in the row. That’s why three cards in a row end up equal height for free.

align-self overrides the cross-axis alignment for one item. Useful when a single icon should sit at the top while its siblings are centered.

Auto margins

An auto margin on a flex item soaks up all the free space on its side. I use this a lot in navigation bars to push one link, like “Log in”, away from the others:

.login-link {
  margin-inline-start: auto;
}

Auto margins are applied before justify-content, so if an item has one, justify-content has no space left to work with.

gap

gap puts space between items and only between them. No space before the first or after the last, and no margin hacks with :last-child.

Centering one thing

The classic. Center a single child both ways:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

The container needs some height for the vertical centering to be visible, otherwise it’s exactly as tall as the child.

Try it on your page: give a container an outline and min-height: 20rem, then turn on the Flexbox overlay and cycle through flex-start, center, space-between, and space-around. Say where the free space is before each change. If you can predict the result, you understand the two axes.

Lesson completed