- Decide whether you need to adjust letter spacing.
- Give each font family its own letter spacing, over the sizes it’s used at.
- Plug them into the formula using
progress().
A scale for tracking
Section titled “A scale for tracking”Fonts come with their own spacing between letters, called tracking, and on the web we usually trust it. But some people want more control. The CSS letter-spacing property adjusts tracking, and its value is added to the font’s own spacing. So 0 keeps the font’s default.
If you want this control, letter spacing should depend on font size. As text gets bigger, letters can appear closer together. This helps Headings take up a little less space while staying readable. As text gets smaller, letters need more space between them to stay legible. In other words, letter spacing goes down as font size goes up.
Some variable fonts already do this. A font with an optical size axis (opsz) can draw its letters differently at each size, often with tighter spacing at larger sizes. Browsers turn this on by default with font-optical-sizing: auto. If your font has this axis, check how its spacing changes before adding the formula below, or the two will stack and the tracking may end up tighter than you want.
WCAG 1.4.12 (Text Spacing) doesn’t set a minimum letter spacing for you to use. Instead, it asks that no content or function is lost when a reader replaces your spacing with their own, up to 0.12 times the font size.
So the negative tracking this chapter works out for larger text is fine, as long as the page still works when a reader overrides it. Avoid fixed widths sized to fit tightly tracked text, since that text will grow wider.
This approach comes from Mathieu Badimon.In his system, sizes of 25px or less get no change. Tracking then tightens by 1% for every 30px, reaching -4% at about 145px.
As before, we’ll use the equation of a line. The setup should look familiar from the Headings chapter:
Here, is the tracking (the letter-spacing value). We need a minimum and maximum for both tracking and font size. In Mathieu’s system, these are:
Since tracking tightens as type size increases, the smallest font size gets the most tracking and the largest gets the least . That’s why the line starts at and moves toward .
Mathieu’s numbers depend on the font, as do all of the variables in these formulas. Adjust them to suit your own font.
Here’s Mathieu’s example in CSS:
.text { --ls-min: -0.04em; --ls-max: 0em; --fs-min: 25px; --fs-max: 145px; letter-spacing: calc( progress(1em, var(--fs-min), var(--fs-max)) * (var(--ls-min) - var(--ls-max)) + var(--ls-max) );}progress() never returns less than 0 or more than 1, so sizes below 25px keep and sizes above 145px keep . There’s no need for a clamp().
By font family
Section titled “By font family”Body and Detail text usually share a font family so the line they both use runs from the Detail size, , to the Body size, . This is an inverse relationship so the smallest text gets the most space. Choose the points to your liking to create the line.
Headings often use a font family of their own. In this system, every Heading sits on the same step of the scale, so there’s no second point to draw a line to. Headings get a single tracking value instead. Because it’s in em, the space between letters increases with the letters, so a fluid Heading looks the same at every size.
.text { font-family: "EB Garamond", serif; --ls-min: -0.01em; /* At the Body size */ --ls-max: 0em; /* At the Detail size */ --fs-min: var(--fs-detail); --fs-max: var(--fs-body); /* The formula from above */
&:where(h1, h2, h3, h4, h5, h6) { font-family: "Gloock", serif; letter-spacing: -0.02em; }}These tracking values are placeholders. Choose your own for each font.
With Heading levels, the line runs from the lowest level’s step on a narrow screen to the top level’s step on a wide one. Use the steps, not the fluid sizes, so the ends of the line don’t move as the window is resized.
Line height works the same way. Each font has its own glyph height and visual leading, so set those wherever the font family changes too.