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.
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/

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:
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?
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.
But yeah, it’s might not be suitable to make such change in a large codebase.