Align texts at the baseline of different font (webfonts)
With web development you sometimes experience problems which seem unsolvable. For example, an art director decides to use a specific web-font for the future development of current webpages and in turn you must implement it instead of Verdana or Arial. Sounds pretty easy, right?
Grab your favourite code to implement @font-face and give the elements of your choice the new font-family. Done. But is it done? Well, maybe. If you chose a new font which looks similar to the old one in letter-spacing, x-height, size etc.
In my specific case I had to style buttons. The font we chose was Fira Sans Medium, the corporate font of Mozilla and FirefoxOS designed by the wonderful Erik Spiekermann. The fallback, and also the previous font for these buttons, was Verdana.
So let’s say you want to center a single line of text vertically in a box with a fixed height, what would you do? Pretty simple, I know, but just to be sure you would take the
height of your box (in my case 40px) and use it also as
line-height for the same element.
Boom. Done. Really?
Dafuq? Baseline? Where you at?
As you can see in the screenshots above, the text is far from centered vertically. Worse in IE than Firefox and Chrome, but all show the same behavior. The text appears to be misaligned and too close to the upper edge. See the CodePen Demo1.
Yes, you could maybe solve this by playing with paddings and line-heights, but would we really want to do this? No. Especially when the browsers behave so differently that you’d need a hack for every single one of them. Plus, this would totally mess up the position of the fallback font if displayed.
Just as I was about to send a screenshot with Verdana and Fira Sans in the same button to Erik and ask him why this strange alignment happens, I realized something had changed when I set up the test cases which should show the baseline difference between the two fonts.
Hooray for frankenfont lines
So what did I set up for my demo? I placed Verdana in the same line as Fira Sans and tt appears as if Verdana forced Fira Sans to align at the Verdana baseline. CodePen Demo2. When I saw this result, the final solution for my problem was close at hand.
We don’t want any extra HTML elements just to align a font where it belongs. Maybe a pseudo element will do. And yes it does. An
:after pseudo element with empty content and with Verdana as
font-family appears to be enough to align Fira Sans where we want to have it. Feel free to play with the final CodePen Demo which is also attached below.
But how? But why?
So yeah, I found a pretty neat solution for my problem, but I don’t really understand how it works under the hood. The order of the fonts don’t seem to have influence on the baseline position. The text always aligns at the Verdana baseline if Verdana is present. I would appreciate it if someone could explain this to me so I can add the explanation to this post. Thank you for your attention.