Your flexbox is actually not centered

Published 7/19/2020

Isn't Flexbox amazing? All these years where we had to fight with floats, try vertical-align: middle only to get disappointed it doesn't work and so many other hacks, then flexbox comes and saves the day.

Centering an element is as simple as

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

Awesome! What a shame if someone would come and try to mess this up right now.

Have you ever realized that when you have two divs (or other elements) below each other, they stick together pixel perfect? But if you have two lines of text, there is actually a little space between them to make it readable. As an example of this, just take a look at this very text right now.

So what's the issue? Well, have a look at this: https://codesandbox.io/s/your-flexbox-is-not-centered-23177

Notice how the left box is not centered correctly. It uses flexbox and has both align-items and justify-content set to center, so what's going on?

If you highlight the text element using the devtools you will see how it has extra space above and below, without any margins or padding. This is line-height. The line-height is usually around 1.5 on most websites, which means it's 1.5 times the font-size. Naturally, this will ruin the vertical spacing due to the additional space the text element now takes up.

The second element in the example has the spacing fixed by explicitly setting the line-height to 1 for this text element.

Now given all of this you might have already realized that this has actually nothing to do with flexbox.

You get the same issues if the box just had padding: 10px for example. It's also not limited to the combination of image + text. You will run into these alignment issues whenever two pieces of text (in a box, like in the example) have different font sizes. This is because, as shown above, line-height is calculated based on the font-size.

An example for this are the listings on dev.to on the right side:

dev.to example

But you can probably find similar examples on most websites out there.

Check out my e-book!

Learn to simplify day-to-day code and the balance between over- and under-engineering.

Now, above we fixed the example by explicitly setting the line-height to 1. The example was super basic, so this worked just fine, but the technique will fall short once you deal with multi-line text. It would become unreadable.

There are some methods out there that add a negative top margin to the element to make it behave like leading in typography.

On top of that, there is actually a proposal to standardize this in CSS. Take a look here.

It surprises me that with all the advancements in web development we have seen over the years, this hasn't made it in yet.