Google Fonts

Vertical metrics

🐸 Vertical metrics are used to determine the space between two lines of text. Some metrics are meant for Mac, others for Windows, and they are interpreted differently according to web or desktop usage.

Throughout countless threads and discussions, GF decided to prioritize cross-platform compatibility and, in consequence, apply the following requirements. Read them carefully because once a family is onboarded, vertical metrics are meant to remain always the same to avoid regression, as mentioned in Adding & upgrading fonts to Google Fonts.

Please note that the first metrics guidelines referred to in this guide are Latin-focused and probably will not fully work for other complex scripts, such as Burmese or Devanagari. CJK fonts (Chinese-Japanese-Korean scripts) are treated as special cases and should follow the instructions at the end of the document.
Background reading:
must→ Adding & upgrading fonts to Google Fonts
must→ Overall font files requirements

Table of contents

Requirements for all fonts (except CJK)

The following rules apply to all new font families and should be enforced for upgraded font families when possible. For font families designed for Chinese, Japanese, and Korean (CJK), please refer to the (CJK Vertical Metrics section below.)

1. Vertical metrics must not be calculated by the font editor automatically

This is an overall best practice in design. When defining line spacing, it’s important to strike a balance between legibility and avoiding overlapping letters. At Google Fonts, we have established a specific system that prioritizes optimal performance for various situations while still leaving room for future update improvements, like adding more languages without causing regressions.

2. Vertical metrics must be consistent across a family.

Each font in a family must share the same vertical metrics values.

This rule can be avoided if a font is being upgraded and previously had inconsistent family metrics. In this case, the aim should be to visually match the line spacing of each font but fix any clipping issues caused by incorrect WinAscent and WinDescent values.

3. If the family is being updated, the line height must visually match the previous release

Some applications do not allow users to control their fonts’ line height/leading. Word processors and text editors are common culprits. It is essential their documents do not reflow.

4. The following vertical metric parameters must be set for each font in a family

OpenType spec (font binaries) Glyphs.app Master customParameter FontLab ufo3 fontinfo.plist
[OS/2] sTypoAscender typoAscender [OS/2] TypoAscender openTypeOS2TypoAscender
[OS/2] sTypoDescender typoDescender [OS/2] TypoDescender openTypeOS2TypoDescender
[OS/2] sTypoLineGap typoLineGap [OS/2] TypoLineGap openTypeOS2TypoLineGap
[hhea] Ascender hheaAscender [hhea] Ascender openTypeHheaAscender
[hhea] Descender hheaDescender [hhea] Descender openTypeHheaDescender
[hhea] LineGap hheaLineGap [hhea] LineGap openTypeHheaLineGap
[OS/2] usWinAscent winAscent [OS/2] WinAscent openTypeOS2WinAscent
[OS/2] usWinDescent winDescent [OS/2] WinDescent openTypeOS2WinDescent

For brevity, we will refer to the three sets of metrics as Typo, Hhea, Win.

5. Use_Typo_Metrics must be enabled

This will force Microsoft Applications to use the Typo values instead of the Win values for line spacing. Doing this allows us to freely set the Win values to avoid clipping and control the line height with the Typo values. It has the added benefit of future line height compatibility. When adding a new script, we simply change the Win values to the latest yMin and yMax without worrying if the line height has changed. Note that the Use_Typo_Metric flag is also called fsSelection bit 7 (related to how it is set in the OS/2 table).

6. WinAscent and WinDescent values must be the same as the family’s tallest/deepest yMin and yMax bounding box values

Microsoft’s OpenType specification recommends the following:

If any clipping is unacceptable, then the value should be set to yMax.

Overpass issue #33 demonstrates what happens in MS applications when the winAscent and winDescent are not set correctly.

Changing these values will increase the line height in MS applications. This can lead to very loose line heights if the bounding box is exceedingly tall. This mainly occurs in families featuring Vietnamese, Devanagari, Arabic, or other tall scripts. To counteract this, we enable the Use Typo Metrics flag and set the Typo values to match the previous Win values. By swapping the sets, we should retain the previous line heights in Windows as well as remove the clipping.

7. Hhea and Typo metrics should be equal

Hhea metrics are used in macOS, while Microsoft uses Typo when Use_Typo_Metrics is enabled. They should ideally be identical.

This rule can be avoided if a font is being upgraded and previously had inconsistent values.

8. LineGap values must be 0

The LineGap value is a space added to the line height created by the union of the (typo/hhea)Ascender and (typo/hhea)Descender. It is handled differently according to the environment. Most desktop apps will add This leading value above the text line. It will be shared above and under in web browsers and ignored in Windows if Use_Typo_Metrics is disabled. For better line spacing consistency across platforms, the (typo/hhea)LineGap values must be 0.

9. Uppercases should be centered in the text line

For fonts whose primary script has uppercase letterforms, such as Latin, Greek, and Cyrillic, web designers will thank you if you manage to have the same space above and under capitals: typoAscender—CapsHeight = abs(typoDescender). It will make it easier for them to set padding in buttons, for example.

10. typo/hheaAscender value should leave open room for stacked diacritics.

Following recent tests to confirm our vertical metrics policies, we now require the (typo/hhea)Ascender to be equal to Abreveacute U+1EAE. For families with multiple weights, you must use the tallest Abreveacute U+1EAE (e.g., in the Black master) as the reference point to guarantee uniform positioning across the entire font family.

Even if the font does not support Vietnamese yet, we strongly suggest estimating the ascenders value foreseeing the Abreveacute U+1EAE height based on two main reasons:

Once the font is published, the vertical metric values cannot be modified. By implementing the above approach, we can keep the option of updating the font in the future to support additional languages like Vietnamese.

11. The sum of the font’s vertical metric values (absolute) should be 20-30% greater than the font’s UPM

By default, DTP applications such as Indesign will set the line height to be 20% greater than the font’s size (10pt size / 12pt leading). For consistency, we recommend setting the vertical metric values so their sum is in a similar range, for example:

UPM = 1000
(typo/hhea)Ascenders = 900
(typo/hhea)Descenders = -300
(typo/hhea)LineGap = 0

Total:
ascender + abs(descenders) + linegap = 1200

Exceptions are usually made if the font’s primary script isn’t Latin, Greek, or Cyrillic. Some scripts such as Devanagari contain very tall and shallow glyphs. It may make more sense for the sum of the metrics to exceed 130% to avoid interline glyph collisions.

Note

Please keep in mind that this calculation will need to be set according to the specificities of each font.

Concrete cases:

Setting vertical metrics usually falls into the following two categories:

  1. Calculating the vertical metrics for a new family
  2. Recalculating the vertical metrics for an upgraded family

1. Calculating the vertical metrics for a new family

Set these values to be the same across all masters to ensure that output instances have equal vertical metrics:

Expected result: vertical metrics should be around 130% of UPM. Anything greater, and the metrics may look too loose.

Example

A new Latin family has the following qualities:

  1. Set the default values following the schema above:
typoAscender = 1015 # which matches the tallest `Abreveacute U+1EAE` in the family (see below)
typoDescender = -315 # an equal or similar value added to the Cap's Height to leave them centered in the line and is greater than the deepest letterform.
typoLineGap = 0
hheaAscender = 1015 # ==typoAscender
hheaDescender = -315 # ==typoDescender
hheaLineGap = 0 # ==typoLineGap
winAscent = 1116 # which matches Font bbox yMax, `Abrevehookabove U+1EB2` in the family 
winDescent = 315 # *absolute value* of Font bbox yMin ie. a positive integer
  1. Be sure to copy these same metric values to all of the masters in the family
  2. Be sure to enable Use_Typo_Metrics
  3. If working in GlyphsApp, you can add the “EditView Line Height” parameter in Font Info and set it up to UPM*1.3 (so 1300 if your UPM value is 1000). This allows you to view your line spacing at the glyph view window.

Note: In step 1, for determining the typoAscender value, matching the tallest Abreveacute in the family is not done with a rote mathematical formula (like ≈ [(UPM * 1.3 - CapsHeight) / 2] + CapsHeight) - because almost nothing is mathematically calculated in typography, but rather it is about proportions, so absolute math may bring more confusion than clarity, even when dealing with a family’s vertical metrics. For instance, once the height of Abreveacute has been established, it can give a sense of how much is being added to the Cap Height. In this example, with a Caps height of 700, according to the math formula, the value would have been 300, but a better fitting proportion is +315 due to its Abreveacute height.

People tend to think that math formulas are more precise and, hence, follow them blindly. On the other hand, if the Abreveacute height is very high, forcing the average vertical metrics to be absurdly tall—way beyond the suggested 130% overall—then the stacked mark positions would need to change to fit better that percentage.

2. Recalculating the vertical metrics for an upgraded family

Many font families receive upgrades, either by the original author or a third party. When character extensions modify the font’s bounding box, the vertical metrics need to be recalculated.

Imagine we have a previous v1.000 release. We’re now adding Vietnamese. The version number has been bumped to V2.000. The font’s bbox yMax has changed from 1000 to 1102 and yMin from -200 to -314.

v1.000 had the following family vertical metrics:

typoAscender = 800
typoDescender = -200
typoLineGap = 200
hheaAscender = 800
hheaDescender = -200
hheaLineGap = 200
winAscent = 1000
winDescent = 200

Notice each set set adds up to 1200, if the negative integers are converted to positive. This should lead to consistent metrics across each platform

There are two cases that can occur.

I. Use_Typo_Metrics was already enabled in the v1.000 release.

  1. v2.000 vertical metrics:

    typoAscender = 900 # Old typoAscender + typoLineGap/2
    typoDescender = -300 # Old typoDescender + typoLineGap/2
    typoLineGap = 0 
    hheaAscender = 900 # typoAsender
    hheaDescender = -300 # typoDescender
    hheaLineGap = 0 # typoLineGap
    WinAscent = 1102 # Font bbox yMax
    WinDescent = 314 # Font bbox yMin (positive integer)
    
  2. Repeat the process for each weight/style if values are not unique in v1.000

II. Use_Typo_Metrics was not enabled in the previous release.

The Typo Metrics need to inherit the v1.000 Win values. The WinAscent and WinDescent also need to reflect the new yMin and yMax values.

  1. v2.000 vertical metrics:

    typoAscender = 1000 # Old WinAscent
    typoDescender = -200 # Old negative WinAscent
    typoLineGap = 0 # Win Metrics has no LineGap parameter so we set this to 0
    hheaAscender = 1000 # typoAscender
    Hhea Descender = -200
    hheaLineGap = 0 # typoLineGap
    winAscent = 1102 # Font bbox yMax
    winDescent = 314 # Font bbox yMin positive integer
    
  2. Repeat the process for each weight/style if values are not unique in v1.000
  3. Enable Use_Typo_Metrics

If the font is already hosted on fonts.google.com, you can confirm the upgraded vertical metrics visually match by using diffenator2 with the command diffenator2 diff -fb font1.ttf -fa font2.ttf -o out_dir where -fb stands for --fonts-before and -fa for --fonts-after.

CJK Vertical Metrics

CJK vertical metrics are based on Source Han Sans and Noto CJK fonts.

The following vertical metric values must be applied to all CJK fonts

Attrib Value Example using 1000upm font
OS/2.sTypoAscender 0.88 * font upm 880
OS/2.sTypoDescender -0.12 * font upm -120
OS/2.sTypoLineGap 0 0
hhea.ascender Set to look comfortable (~1.16 * upm) 1160
hhea.descender Set to look comfortable (~0.288 * upm) -288
hhea.lineGap 0 0
OS/2.usWinAscent Same as hhea.ascent 1160
OS/2.usWinDescent abs(value) of hhea.descent 288
OS/2.fsSelection bit 7 (Use_Typo_Metrics) Do not set / disabled 0

Our decision to follow the Adobe schema was based on Dr. Ken Lunde’s comments and his release notes on Source Han Sans: