Web design: vertical metrics puzzle

Why does the very same font behave differently in InDesign and Chrome? Why does it look shifted on a button in Figma? Who’s to blame, a type designer, a web designer or a developer? In this article, we’ll try to cover the main scenarios and aspects of the work process and find out whether it is possible to avoid inconsistencies. (Spoiler alert: it’s complicated).

March 7, 2024

Graphic designers work in a single environment (e.g. Adobe Illustrator), and then export fixed files for print. However, UX/UI designers deal with dynamic layouts that are meant to be rendered in various systems and may exhibit inconsistent behaviour. That fact defined how different the text containers might behave in applications created for graphic and UX/UI design.

01 Containers in Figma (left) and InDesign (right)
Set in Proto Grotesk

The position of text in the container is bound to the font’s vertical metrics. But there’s a number of such metrics and it’s up to a particular browser, or software, to determine which metrics to rely on.

02 Containers in Figma. Text size 200 pt
Set in Roslindale и Zapfino

Although modern browsers generally exhibit consistent font display behaviour, occasional inconsistency may arise in both older fonts and newer ones that follow the best contemporary practices in setting vertical metrics.

Unusual or inconsistent font behaviour can stem from various stages in the process of creating a web product. To identify the solution, we’ll explore three key points of view within the web product creation process.

POV: Web developer

Before the arrival of Sketch, Figma and Adobe XD, designers handed to developers files for the web created in Photoshop. Developers then had to install the OTF/TTF fonts locally on their computers. In this case, the Photoshop layout served as a certain reference point, since the logic used by graphic editor software is different from the one used when dealing with the web. The arrival of Sketch and Figma facilitated the work for web developers, as now they can copy the parameters of most blocks and transfer them to the web, sticking to the pixel-perfect concept. A pixel-perfect website should perfectly match the Figma file, which means a web developer has to take into consideration all the optical compensations planned by a designer. For instance, designers often need optical compensations to position text in the centre of a button.

03 Buttons without optical compensations (left) and with them (right)
Set in Rooftop

A WOFF font that a developer will use on the website needs to have the same metrics as an OTF font that a designer used for their Figma mockup. But even if a font was properly prepared for the web environment, one can still face some issues during a developing process.

Different software, including browsers, employs different rendering mechanisms, making the same font look non-identical (for example, bolder or lighter) in different browsers. Although modern browsers generally exhibit consistency in the vertical positioning of fonts, preventing vertical shifts across platforms, visual differences may still occur, especially with fonts created before browsers had become consistent in handling the vertical metrics.

Typically, developers address this issue by specifying various font parameters in CSS and using the CSS Reset file which is commonly used to reset default stylesheet settings of the browsers, such as left or top margins, or additional font strokes.

04 The same typeface on the same website in different browsers: Firefox (left) and Chrome (right). Image: Reddit

It may happen that a client purchases the required web font licence just before the launch rather than before embarking on making a website. This practice not only violates the terms of many licences, but also leads to a number of problems. The WOFF file converted by a client from an OTF/TTF file can differ in terms of its metrics from a WOFF file created by a type designer. Which is why a web developer who received a WOFF file the night before the launch might not be able to just replace one file with another, and, if the WOFF file turns out to be improperly prepared, they won’t have time to reach out to a type designer.

POV: Web designer

Adobe tools like InDesign were designed to work with printed materials and a designer calculates spaces between text blocks based on a modular grid, which is in turn arbitrarily linked to line spacing — whereas Figma follows the web logic and uses a pixel grid, so a designer first and foremost pays attention to the columns and the height of text containers.

05 Grids in Figma (left) and InDesign (right)
Set in Flicker and Graphik

Up until recently, text containers in Figma used their own method for calculating line heights which caused a number of issues.

For instance, if the upper edge was set to be higher than an uppercase accented character, and a container carried just one word set in lowercase, the distance to the container’s upper boundary appeared larger than the distance to its lower boundary. And if the line height is set to be more than auto to a block which contains only one line, the space will still be added to the top of this block as well as its bottom.

If a font has unusually tall ascenders and descenders or a very small x-height, and a container carries just one lowercase word, the distance to the container’s upper boundary appears larger than the distance to its lower boundary.

06 Line height 100% and 175%
Set in Graphik

But not so long ago Figma started inviting users to choose the way a container will be displayed. You now can pick the one that relies on the cap height. This update happened because Figma wants to be consistent with the web, and CSS has been announcing a property for this for a long time already (currently this kind of vertical trim is supported by Safari only).

07 Standard vertical trim and Cap height to baseline trim
Set in Halvar

And even though leading trim might help align an icon to a button with text, it is far from being an universally applicable option as Figma doesn’t take into consideration all the languages and scripts that go beyond basic Latin and Cyrillic yet.

08 Vietnamese with diacritics extending above the container’s upper border
Set in Gentium

In Georgian, container boundaries are defined by Mtavruli (a display style, an equivalent to All Caps), which means that the feature works improperly when it comes to Mkhedruli (a style which does not recognise capital letters, mainly used for Georgian language).

09 Mkhedruli (left) и Mtavruli (right)
Шрифт: Loos

It gets even more complicated when a project uses two scripts with drastically different vertical metrics in terms of their vertical metrics, such as Latin and Tamil.

10 Latin and Tamil in a Figma-container
Set in Noto Sans

Objects in Figma layouts are often grouped by components. So, if you apply the leading trim to the already finished projects, the sizes of components will change and a web developer won’t be able to figure out the layout. Which is why most designers continue to calculate indents from the container’s border.

11 Finished layout. Standard vertical trim (left) and changed vertical trim (right)
Set in Graphik

If you intend to calculate indents based on the cap height in your new project, you’d better notify the developer. It might be complicated for them to work with such a design, if they copy (directly or using a plugin) CSS values from Figma to a layout they are working on.

POV: Type designer

Apart from drawing a typeface, type designers set certain technical parameters in a font file, so that a font would work properly. Amongst other parameters, there are sets of vertical metrics that determine certain heights (baseline, highest and lowest points, default line height, etc.) in order to display the font in a particular environment.

12 Vertical metrics input window in Glyphs

Vertical metrics input window in Robofont

Historically, different sets of vertical metrics were created for different operation systems and could significantly differ from each other, therefore leaving a wide range of ways for type designers to set vertical metrics. That could have led to inconsistent display across platforms so type designers would work out the best possible correlation of parameters for each font individually.

15 Hhea metrics in Vertical-metrics.netlify app. Safari (left) and Firefox (right)
Set in SangBleu Sunrise

Nowadays, there are several strategies for setting up the vertical metrics sets that are supposed to make the fonts behave consistently. The choice of a strategy would still depend on the task, but there is more unity in filling up the parameters amongst different fonts made by different type designers.

Overall, these strategies can be divided into the recommended ones for new fonts and the legacy ones for the old fonts. But there are several offered standards from different companies and their vision of recommended and legacy ones differs slightly as well.

In case you need to set vertical metrics in your font file, get acquainted with these links:

1. Font development best practices handbook by SIL
2. Vertical metrics guide by Glyphs app
3. Vertical metrics setting rules by Google Fonts.

Font editor tools have three sets of vertical metrics: Hhea, Typo, Win. The recommended strategies suggest calculating Hhea and Typo metrics according to a script the font is being designed (primarily) for. Some of the strategies suggest to base calculations on certain glyphs, for example Google requires the highest point for Hhea and Typo to be taller than À. But overall, type designers aim to set these metrics to a span of tallest and lowest elements, which are usually descenders and ascenders (and sometimes, accents), in order to provide optically centred text and an appropriate default line spacing.

In newer fonts, Hhea and Typo are most often made the same in order to minimise the difference in the way the font gets rendered on different devices.

Win metrics must contain the highest and the lowest points in a given font in order to avoid clipping in certain environments like Office Word. Such points can be located, for example, on symbols with diacritics or non-alphabetical glyphs.

16 Font’s metrics and Figma container with the glyphs defining metrics in it
Set in Graphik

If a designer sets Hhea and Typo metrics the same as Win and there is a big difference between heights of letters and tallest/lowest glyphs in a font, the line spacing in a font would be huge and that will affect font display on the web.

But there can be situations where all metrics are equal. For example, if a font is designed for a specific task and, for instance, supports just one alphabet or has a small glyphs set.

17 Metrics in Noto Sans Math designed for math papers

On the contrary, it can also happen that you have to bring together a number of fundamentally different scripts in one font file — for example, Latin and Hangul, or Cyrillic and Arabic. The difference between heights and positions of letters (and whether the script has different cases or not) directly affects how the text in both scripts is positioned. In this case, a designer finds compromise metrics values — so as to avoid clipping accents in one language and prevent a text block from having excessive line height in the other.

18 Vertical metrics of a font with Latin and Arabic support in Vertical-metrics.netlify app
Set in Spektra

Historically, Win and Typo were used in Windows products, while Apple platforms embraced Hhea metrics. Any particular software could always make their own choice of what metrics to rely on (or even ignore them completely).

Figma containers are confined to hhea metrics. While this decision has reasoning, there can be particular scenarios of a poor display of a font. For example, a web designer might create a button and see that the word in it appears shifted towards the bottom. This is not a rare case, and often, the issue doesn’t come from an error in a font file, but rather from the drawing of a particular typeface: it can have large capitals and small x-height that define the font’s vertical metrics.

19 Set in Loos, Stratos, Proto Grotesk

The shifted display of a font might also be caused by the need of a type designer to balance the font between the risk of clipping and the risk of too huge (or too small) line height. Problems might as well appear only in a specific environment (browser, tool) while everywhere else the font file is working properly.

There’s no way to make a font be uniformly displayed in just any environment. That is why the only thing a type designer can do is to consider the task, decide on a strategy and specify the metrics according to them, so that the font is displayed correctly in as many environments as possible without any of its elements getting cut.

So what do I do now?

If you are a web designer who faced an issue of abnormal positioning of a font, make sure that the web developer took into consideration all the optical compensations that you’ve implemented. In case you are positive that they did, ask the developer whether the issue could be fixed with the means of CSS (but this might be difficult in a complex project). If not, reach out to the font’s author. Then, most likely, the designer can adjust the font (though this will probably affect your project’s timing and budget).

If you are a type designer, take a look at the best contemporary practices of setting the font’s vertical metrics. And if there is a particular situation where your font doesn’t work as expected, consider if it makes sense to update your font or create a separate version for a specific task.

However, there are no universal solutions. It makes sense to address any given issue separately, taking into account the specifics of any given project.

Special thanks to Frank Grießhammer, Liang Hai (梁海), Rutherford Craze, Alexander Moskovskiy and Alexander Balchunas for invaluable inputs, feedback and review.


Mentioned fonts