Complete the lesson quiz and earn 250 XP.
Over 90% of information on the web and in mobile apps is presented as written language. Typography is not merely graphic decoration; it is the primary user interface through which users comprehend products, navigate flows, and make decisions.
A disciplined typography system achieves three critical UX goals:
h1), section dividers (h2), card headers (h3), and supporting body copy.Rather than randomly choosing arbitrary font sizes like 14px, 19px, 23px, and 37px, typography systems use a modular scale—a sequence of font sizes generated by multiplying a base size (usually 16px) by a fixed mathematical ratio.
Common Modular Scales:
Line height (known in print as leading) is the vertical space between lines of text. Incorrect line height ruins legibility.
The Inverse Proportion Rule:
As font size increases, relative line height must decrease.
1.4 to 1.6). When users read multi-line paragraphs, ample line height prevents the eye from accidentally skipping lines when returning to the left margin.1.1 to 1.25). At large sizes, a 150% line height spreads words so far apart that multi-line headings look like disconnected sentences.Letter spacing (CSS letter-spacing) controls the uniform spacing across all characters in a text block. Fonts are typically designed to look best at body sizes (14–16px). When scaled up or down, optical physics requires adjustment:
-0.02em to -0.03em).+0.05em to +0.12em) to open up breathing room.0 (normal); let the font designer's default kerning pairs do their job.The horizontal length of a text block is called its measure. Measure is one of the most critical factors in reading comfort:
The Golden Measure: Optimal body text measure is between 45 and 75 characters per line (including spaces). In CSS, this is achieved using character units: max-width: 65ch;.
Many web fonts offer up to 9 weights (from Thin 100 to Black 900). Downloading all 9 weights adds massive performance bloat (hundreds of kilobytes of font files).
High-performing design systems standardize on 3 to 4 core weights and assign each a clear semantic role:
h1, h2) and critical statistical metrics.Avoid using weights below 400 (Light/Thin) on digital screens: thin fonts look frail on low-DPI displays and fail accessibility contrast standards.
By default, most modern fonts use proportional numerals: the digit 1 is much narrower than the digit 8 or 0. In body paragraphs, proportional figures look natural and elegant.
However, in data tables, financial ledgers, and countdown timers, proportional numbers cause an unsightly problem: columns of numbers wobble and fail to align vertically:
Proportional: Tabular (Fixed Width):
$1,111.11 $1,111.11
$8,888.88 $8,888.88
Design systems solve this by activating OpenType tabular figures:
.font-tabular {
font-variant-numeric: tabular-nums;
}
This ensures all digits share an identical bounding width, keeping decimals and columns perfectly straight.
When architecting a typography system, teams face a strategic decision:
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif):
Pro Tip: If using web fonts, always preload the primary WOFF2 files and use font-display: swap so content remains readable immediately.
In the past, responsive typography required dozens of @media queries with stepped jumps: at 768px, a headline would abruptly snap from 32px to 44px.
Modern design systems use fluid typography via CSS clamp():
:root {
--font-size-display: clamp(2rem, 1.5rem + 2.5vw, 3.75rem);
}
2rem (32px): The minimum font size on mobile screens.1.5rem + 2.5vw: The preferred fluid rate, growing smoothly as viewport width expands.3.75rem (60px): The maximum font size cap on ultra-wide desktop monitors.Fluid scales eliminate abrupt visual jumps, ensuring headings scale gracefully across foldable phones, tablets, laptops, and 4K displays.
Let's synthesize our complete typography system into a clean, reusable token set:
{
"typography": {
"display-2xl": { "size": "48px", "lineHeight": "1.15", "tracking": "-0.025em", "weight": "800" },
"heading-xl": { "size": "32px", "lineHeight": "1.25", "tracking": "-0.02em", "weight": "700" },
"heading-md": { "size": "20px", "lineHeight": "1.35", "tracking": "-0.01em", "weight": "600" },
"body-base": { "size": "16px", "lineHeight": "1.5", "tracking": "0em", "weight": "400" },
"caption-sm": { "size": "12px", "lineHeight": "1.4", "tracking": "+0.02em", "weight": "500" },
"overline-xs": { "size": "11px", "lineHeight": "1.3", "tracking": "+0.12em", "weight": "800", "transform": "uppercase" }
}
}
Notice how every typography token bundles size, line height, letter spacing, and weight into an indivisible composite token.