Esc
  • Design SystemsFrom Figma Variables to Tailwind, Without the Copy-PasteDesign tokens only help if design and code read from the same source. Here's how I set up a pipeline where Figma variables become Tailwind theme values and React props, and what I learned about naming along the way.
  • Next.jsBuilding a Like Button, From Database to DelightThe heart at the bottom of every article on this site is a tiny full-stack feature. Here's how it works, from the SQLite table and API route to optimistic updates and batched requests.
  • AnimationA Friendly Introduction to Spring PhysicsSprings make interfaces feel alive. Instead of picking a duration and an easing curve, you describe how something should move, and physics does the rest. Let's build an intuition for stiffness and damping with a live playground.
  • UI DesignDesigning Dashboards People Can Actually ScanData-heavy screens fail when every number shouts at once. A practical guide to hierarchy, tables, filters and progressive disclosure for dashboards that engineers and analysts use all day.
  • CSSUnderstanding Flexbox Alignment, Visuallyjustify-content or align-items? Main axis or cross axis? If you still guess which property to use, this interactive guide will fix that for good.
  • BrandA Brand System Is More Than a LogoA logo is the smallest part of a brand. What makes a brand recognizable is the system around it, from type and color to iconography, voice and the way the product itself behaves. Here's how I approach building one that survives contact with real products.
CSS

Understanding Flexbox Alignment, Visually

justify-content or align-items? Main axis or cross axis? If you still guess which property to use, this interactive guide will fix that for good.

2 min read…

Here's a confession: for years, every time I needed to center something with Flexbox, I'd try justify-content, see that it did the wrong thing, and switch to align-items. It worked, but I didn't really understand why.

The secret is that Flexbox alignment isn't about horizontal and vertical. It's about axes.

The primary axis and the cross axis

Every flex container has two axes:

  • The primary axis (often called the main axis) runs in the direction set by flex-direction. With the default row, it goes left to right.
  • The cross axis is perpendicular to it.

And the two properties map neatly onto them:

  • justify-content distributes items along the primary axis.
  • align-items positions items along the cross axis.

That's the whole mental model. When you flip flex-direction to column, the axes rotate, and so do the effects of both properties. Try it:

flex-direction
justify-content
align-items
1
2
3
.container {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: stretch;
}

Why "justify" and "align" behave differently

You might notice that justify-content has options like space-between, while align-items has stretch and baseline. That's because they solve different problems.

Along the primary axis, items are laid out as a group. They sit side by side, so the question is how to distribute the leftover space between them.

Along the cross axis, each item is positioned individually. There's no "between" to worry about. Each item just decides where it sits in its own lane, which is why you can override it per item:

CSS
.special-item {
  align-self: flex-end;
}

Perfect centering, explained

So the classic centering snippet makes complete sense now:

CSS
.center {
  display: flex;
  justify-content: center; /* primary axis */
  align-items: center;     /* cross axis */
}

We center the group along the primary axis, then center each item along the cross axis. No guessing required.

A quick cheat sheet

  1. Decide which way your items flow. That's flex-direction, and it defines the primary axis.
  2. Use justify-content to distribute items along that flow.
  3. Use align-items to position them in the other direction.
  4. Reach for align-self or auto margins to break the rules for a single item.

Once you start thinking in axes, Flexbox stops being a guessing game.

Want to know when I publish something new?

I send a short email when there's a new article or project, usually a couple of times a month. No spam, and you can unsubscribe whenever you like.