UX Encyclopedia

Typography for Interfaces

Type is ~90% of most interfaces' visual matter. Get it right and the rest gets easier.

Try it — line length (measure). Drag to change the column width and watch when reading gets uncomfortable. The 45–75 character zone is marked.

Legibility fundamentals (research-backed)

Line height — ~1.4–1.6× for body, tighter for big headings. Real rendered text, judge for yourself.
Casing — ascenders/descenders give lowercase words distinct silhouettes; ALL CAPS reads slower in running text. Fine for short labels.
  • Size: Body text minimums by convention of the platform owners: 17 pt (iOS default body, Apple HIG), 16 sp (Material body-large), ~16 px on the web (browser default; going smaller measurably slows reading for many users). Legge & Bigelow (2011) show reading speed is stable across a broad middle range of sizes and collapses below a critical print size — so err larger, especially for older users.
  • Line length (measure): ~45–75 characters per line for comfortable reading of body text (classic typographic guidance, Bringhurst). Very long lines make return sweeps error-prone; very short lines fragment reading.
  • Line height: ~1.4–1.6× font size for body text; tighter (1.1–1.3) for large headings. (Convention; WCAG 1.4.12 requires text to survive user overrides up to 1.5 line-height.)
  • Contrast: WCAG AA = 4.5:1 for normal text, 3:1 for large text (≥18 pt / 14 pt bold). Pure black on pure white is allowed and fine; claims that it causes eye strain are anecdotal, not established research.
  • Casing: ALL CAPS slows continuous reading (uniform word shapes, and people have little practice reading caps); fine for short labels.
  • Serif vs. sans on screens: modern research finds no consistent legibility winner at adequate sizes/resolutions; choose by tone and rendering quality, not folklore.

System of styles (type scale)

A role-based scale at ratio ≈1.25, rendered at true size. Name the roles, not the pixels — then the whole product speaks with one voice. Exact per-platform values: Type Scale Cheat Sheet.
  • Define roles, not ad-hoc sizes: display, headline, title, body, label / caption (this mirrors Material 3's and Apple's role-based scales).
  • Build the scale on a ratio (e.g., 1.2 "minor third" or 1.25) or adopt a platform scale; limit to ~5–7 sizes and 2–3 weights actually used.
  • Hierarchy via weight and size, sparingly via color; never via underline (reserved for links on the web).
  • Pair at most 2 typefaces (one display/brand voice + one workhorse); a monospace third only if you display code/data.

Font pairing craft (conventions of the trade)

Pair by contrast of role, harmony of proportion. Set the same sentence in both faces at body size — if one looks 10% bigger, compensate or re-pair.
  • Pair by contrast of role, harmony of proportion: the two faces should differ obviously (serif display + sans body, or grotesque + humanist) but share similar x-height and apparent size — set the same sentence in both at body size; if one looks 10% bigger, compensate or repair.
  • Near-miss pairs (two similar sans faces) read as a mistake, not a choice — make the difference decisive or use one family.
  • Cheapest safe route: a superfamily designed to match (e.g., Source Serif/Sans, IBM Plex Serif/Sans/Mono).
  • Judge pairs in a realistic mockup at real sizes, not in a specimen sheet; display-only faces often collapse below ~20 px.

Variable fonts

This figure is the site's own variable font (Bricolage Grotesque) — every weight and both optical sizes come from one file. Intermediate weights like 450/550 tune hierarchy and dark-mode rendering.

One file exposing continuous design axes (weight wght, width wdth, optical size opsz, slant, custom axes) — OpenType 1.8 spec, 2016; well supported in all modern browsers and OSes.

  • Performance: one variable file usually beats 3–4 static weights; subset it and serve WOFF2.
  • Fine hierarchy: intermediate weights (e.g., 450, 550) tune emphasis and fix light-text-on-dark looking heavier (drop ~50 weight units in dark mode — a common convention, not a standard).
  • Optical sizing: opsz makes small text sturdier and display text finer automatically (font-optical-sizing: auto). SF Pro, Segoe UI Variable, and Roboto Flex all do this; it's why platform type looks right at every size.
  • CSS: prefer high-level properties (font-weight: 450) over raw font-variation-settings, which disables property inheritance niceties.

Numerals: tabular figures & friends

Live rendering: ones in proportional figures are narrow, so columns wobble; tabular-nums fixes it. Try the interactive version on Data Tables & Dashboards.
  • In tables, timers, prices, dashboards, and anything that updates in place, use tabular lining figures (font-variant-numeric: tabular-nums) so digits share one width — columns align and counters don't jitter.
  • Proportional figures are for running text; oldstyle figures (lowercase- like) suit editorial prose, not UI data.
  • If the font lacks a tnum feature, pick a different font for data surfaces; letter-spacing hacks don't fix digit widths.
  • Related OpenType niceties: slashed-zero for codes/IDs, diagonal- fractions for recipes/measurements.

Fluid type (web)

Fluid type with clamp: font size holds at a minimum below narrow viewports, scales linearly with viewport width between anchors, and stops at a maximum. min 1.75rem max 3rem preferred: 1.2rem + 2vw 320px1280px viewport width font size
clamp(1.75rem, 1.2rem + 2vw, 3rem) — flat at the anchors, fluid between. The rem term keeps zoom and user font-size working (WCAG 1.4.4); headings get fluidity, body mostly doesn't need it.
  • clamp(min, preferred, max) with a rem + vw preferred term scales type smoothly between breakpoints, e.g. font-size: clamp(1.75rem, 1.2rem + 2vw, 3rem).
  • Always include a rem component and sane min/max: pure-vw sizing ignores browser zoom and user font-size, risking WCAG 1.4.4 (resize to 200%) failures. Verify text still enlarges at 200% zoom.
  • Scale display/headline sizes fluidly; keep body ~16–18 px across viewports — body text needs little fluidity, headings need a lot.
  • Utopia (utopia.fyi, Clearleft) is the common calculator for coordinated fluid type + space scales.

Platform notes

  • iOS/macOS: San Francisco (SF Pro / SF Compact); support Dynamic Type (user-scalable text) — Apple treats this as an accessibility requirement.
  • Android: Roboto (Material default) / Google Sans in Google apps; sizes in sp so they scale with user settings.
  • Windows: Segoe UI Variable (Fluent 2 type ramp).
  • Web: use rem units so text respects browser settings; load ≤2 font families, subset weights, use font-display: swap.

Sources

  • Bringhurst, R. The Elements of Typographic Style (Hartley & Marks) — measure, rhythm, scale.
  • Legge, G. E. & Bigelow, C. A. (2011). "Does print size matter for reading?" Journal of Vision, 11(5).
  • Microsoft OpenType specification v1.8 (2016) — font variations (variable fonts).
  • Apple Human Interface Guidelines — Typography (developer.apple.com/design).
  • Material Design 3 — Typography / type scale (m3.material.io).
  • Microsoft Fluent 2 — Typography (fluent2.microsoft.design).
  • W3C WCAG 2.2 — SC 1.4.3 (contrast), 1.4.4 (resize), 1.4.12 (text spacing).
  • MDN — font-variant-numeric, font-optical-sizing, clamp() (developer.mozilla.org).
↑↓ to navigate · Enter to open · Esc to close