Analysis on a vertical alignment issue in CSS

So I came across this blog post when browsing Aha!'s engineering blog. The acknowledgement that CSS is challenging and the methodically structured approach they are taking to address the problem resonates with me.

At the end of the article, it states, "If you know the reason or have a different solution, we would love to hear from you." So, here I am, attempting to find a reason and perhaps offer a different solution.

The Problem

An img tag causing misalignment.

Refresh page to view  or  View on CodePen .

The Cause

After some sandboxing and googling around, it appears the issue is related to baseline alignment. By examining the DOM tree structure, we can divide it into two parts: the alignment of the two inline-box pill span elements and the determination of the baseline for the wrapper flex container.

1. Inline box baseline alignment

According to w3 document for baseline alignment:

While most CSS formatting contexts position content by aligning boxes with respect to their container’s edges, inline layout positions boxes in the block axis by aligning them with respect to each other using their baselines.

A very clear example from here: https://infoheap.com/css-inline-block-baseline-alignment/

image

Refresh page to view  or  View on CodePen .

So back to our problem, the “Pill 2”’s baseline somehow lies on img tag. But why?

2. Determining flex container baseline

Understanding related rules in w3 is quite challenging: https://www.w3.org/TR/css-flexbox-1/#flex-baselines

A plausible(wild) guess would be that it falls in to the second rule:

if the flex container has at least one flex item, the flex container’s first/last main-axis baseline set is generated from the alignment baseline of the startmost/endmost flex item.

So in the original problem, the alignment baseline of the flexbox container corresponds to the alignment baseline of the first flex item, which is the img alignment baseline.

Here is an example where the first element is bigger than the second:

Refresh page to view  or  View on CodePen .

The solution in the original blog post works because it adds a zero width space first child, which has a same height as the second child since they have the same default font size.

But what if they don’t have the same height?

Refresh page to view  or  View on CodePen .

Here, text in span are set to 32px explicitly, but the content in the pseudo element is still default to 16px. Boom, misaligned again.

Alternative solution

Wrap them around a flexbox container.

Refresh page to view  or  View on CodePen .

But yeah, it’s might not be suitable to make such change in a large codebase.