Typography for UI Design
Apply typography systematically to buttons, forms, tables, navigation, cards, modals, dropdowns, toasts, and tooltips in modern design systems.
Interface typography operates under different constraints than editorial typography. UI text is read in fragments — labels, values, statuses, actions — not in sustained paragraphs. Users scan interfaces in milliseconds, make decisions, and move on. Every typographic choice in a UI component must prioritize legibility at small sizes, clarity at a glance, and consistency across hundreds of instances.
This chapter maps typography decisions to the components that compose modern design systems, with reference patterns drawn from established systems including Material Design, Apple Human Interface Guidelines, and contemporary SaaS products like Linear, Stripe, and Vercel.
UI Typography Principles
Four principles govern interface typography:
-
Clarity over expression. UI type communicates function. Decorative choices that work on marketing pages fail in a settings panel.
-
Size down, weight up. UI text runs smaller than body copy (12–14px vs. 16px). Compensate with medium weight (500) for labels and semibold (600) for emphasis rather than relying on size alone.
-
Two-font maximum. One sans-serif for all UI text. Add a monospace for code. A display serif for marketing headings is optional but should not appear inside application components.
-
Token everything. Every font size, weight, line height, and letter-spacing value should be a named token. No magic numbers in component CSS.
Type Scale for UI
UI type scales are tighter than editorial scales. A Major Third (1.25) or even a Minor Third (1.2) ratio prevents size proliferation across components.
A practical UI scale at 14px base:
| Token | Size | Use | |-------|------|-----| | xs | 11px (0.6875rem) | Timestamps, badges, legal | | sm | 12px (0.75rem) | Captions, helper text, table metadata | | base | 14px (0.875rem) | Default UI text, labels, inputs | | lg | 16px (1rem) | Emphasized body, modal titles | | xl | 18px (1.125rem) | Section headings, card titles | | 2xl | 22px (1.375rem) | Page titles, dialog headings |
Note the 14px base — one step below the 16px editorial standard. UI interfaces pack more information into less space, and 14px sans-serif text with appropriate weight and line height remains legible for interface tasks.
Buttons
Buttons are the most interacted-with typographic element in any interface. Their text must be instantly readable and clearly actionable.
Rules:
- Font size: 14px (default), 12px (compact/small), 16px (large/hero CTA)
- Font weight: 500 (medium) — never regular (400) for button labels
- Letter-spacing: +0.01em to +0.025em for clarity at compact sizes
- Text transform: sentence case (preferred) or capitalize. Avoid all-caps except for small secondary buttons where tracking compensates (+0.05em)
- Line height: 1 (single line, vertically centered by padding)
- Minimum touch target: 44px height regardless of text size
- Icon + text: 4–8px gap; icon at 16px for default buttons, 14px for small
.button {
font-size: var(--text-base); /* 14px */
font-weight: 500;
letter-spacing: 0.015em;
line-height: 1;
padding: 8px 16px;
}
.button--sm {
font-size: var(--text-sm); /* 12px */
padding: 6px 12px;
}
.button--lg {
font-size: var(--text-lg); /* 16px */
padding: 12px 24px;
}Forms
Forms combine multiple text roles — labels, input values, placeholders, helper text, and error messages — each requiring distinct typographic treatment.
Rules:
- Labels: sm (12–14px), medium weight (500), sentence case. Position above input with 4–8px gap.
- Input text: base (14–16px), regular weight (400). Users type at this size — do not go below 16px on mobile to prevent iOS zoom-on-focus.
- Placeholder text: same size as input, regular weight, muted color (never as the only label — accessibility requirement).
- Helper text: xs–sm (11–12px), regular weight, muted color, 4px below input.
- Error messages: xs–sm (11–12px), medium weight (500), error color, with icon. Must not rely on color alone — include text.
- Required indicators: asterisk or "(required)" at label size, error or accent color.
Tables
Tables are typography-intensive — headers, cell data, sorting indicators, pagination, and empty states all compete for attention.
Rules:
- Header row: sm (12–14px), semibold (600), uppercase with +0.03em tracking OR sentence case at medium weight (500). Sticky headers for scrollable tables.
- Cell data: sm–base (13–14px), regular weight (400). Tabular figures for numeric columns.
- Secondary cell data: xs–sm (11–12px), muted color. Timestamps, IDs, metadata.
- Row height: minimum 40px (48px preferred for touch). Vertical padding, not line-height, controls row height.
- Alignment: text left, numbers right, status/icons center. Consistent across all rows.
- Empty state: base size, centered, muted. "No results" message with action suggestion.
Navigation
Navigation typography establishes wayfinding without demanding attention.
Rules:
- Primary nav items: sm–base (13–14px), medium weight (500) for active, regular (400) for inactive.
- Secondary/utility nav: sm (12–13px), regular weight. Settings, profile, help links.
- Breadcrumbs: sm (12–13px), regular weight, separator at muted color. Current page at medium weight.
- Sidebar navigation: sm–base (13–14px). Section headers at xs–sm (11–12px), uppercase with tracking (+0.05em) or semibold sentence case. Active item: medium weight + accent color or background.
- Tab labels: sm–base (13–14px), medium weight for active tab, regular for inactive.
Cards
Cards bundle related content with a clear typographic hierarchy in a compact space.
Rules:
- Card title: base–lg (14–16px), semibold (600). One line preferred; truncate with ellipsis if necessary.
- Card description: sm–base (13–14px), regular weight (400), muted color. Two to three lines maximum; truncate beyond.
- Card metadata: xs–sm (11–12px), regular weight, muted. Date, author, category.
- Card actions: sm (12–14px), medium weight. Text links or small buttons.
- Spacing: 12–16px padding. Title-to-description gap: 4–8px. Description-to-action gap: 12–16px.
Modals and Dialogs
Modals interrupt workflow and demand immediate comprehension. Typography must be concise and hierarchical.
Rules:
- Dialog title: lg–xl (16–18px), semibold (600). One line; refine copy if wrapping occurs.
- Dialog body: base (14px), regular weight, 1.5 line height. Two to three sentences maximum for confirmation dialogs.
- Dialog actions: button typography (see Buttons). Primary action first (right-aligned in LTR layouts) or last (following platform convention).
- Destructive dialogs: title and body follow standard rules. Destructive action button uses error color; text remains standard button typography.
- Spacing: 24–32px padding. Title-to-body: 8–12px. Body-to-actions: 24px.
Dropdowns and Select Menus
Dropdowns present options in a compact overlay. Legibility at sm size is critical.
Rules:
- Trigger text: base (14px), regular weight. Selected value displayed at same size as input text.
- Menu items: sm–base (13–14px), regular weight. Medium weight for selected item.
- Group labels: xs (11–12px), semibold or uppercase with tracking, muted color.
- Item descriptions: xs (11–12px), regular weight, muted. Below primary item text with 2px gap.
- Max visible items: 6–8 before scroll. Menu width matches or exceeds trigger width.
Toasts and Notifications
Toasts appear briefly and must communicate status in one glance.
Rules:
- Toast title: sm (13–14px), medium weight (500). Optional — single-line toasts may omit title.
- Toast message: sm (12–13px), regular weight (400). One to two lines maximum.
- Toast action: sm (12–13px), medium weight, accent color. Text link style.
- Duration text: xs (11px), muted. "Undo" or "Dismiss" actions.
- Icon: 16–20px, aligned to first line of text. 8px gap between icon and text.
Tooltips
Tooltips provide supplementary information on hover or focus. They are the smallest text in the system.
Rules:
- Tooltip text: xs (11–12px), regular weight (400). One to two lines maximum.
- Line height: 1.3–1.4 (tighter than body text).
- Padding: 4–8px vertical, 8–12px horizontal.
- Max width: 200–240px (approximately 30–40 characters per line).
- Do not put essential information in tooltips. They are inaccessible to touch users and keyboard-only users without deliberate implementation.
Design System Reference Patterns
Established design systems provide tested starting points:
Material Design 3
- Body: 14px/20px (size/line-height), weight 400
- Label: 14px/20px, weight 500
- Title: 16px/24px (medium), 22px/28px (large), weight 400
- Headline: 24px/32px (small), 28px/36px (medium), weight 400
- Display: 36px/44px (small) through 57px/64px (large), weight 400
Material uses weight 400 throughout, relying on size differentiation alone. This works at Google's scale with Roboto's generous x-height but may feel too light in smaller products.
Apple HIG
- Body: 17px (iOS), weight 400
- Callout: 16px, weight 400
- Subhead: 15px, weight 400
- Footnote: 13px, weight 400
- Caption: 12px, weight 400
- Headline: 17px, weight 600 (semibold)
- Title: 28px (large), 22px (medium), 20px (small), weight 700 (bold)
Apple compensates for fewer weight variations with larger base sizes and bolder headings.
Contemporary SaaS (Linear, Stripe, Vercel)
These products converge on similar patterns:
- Base UI: 13–14px, weight 400–500
- Headings: 14–16px (semibold 600), not large display sizes
- Monospace for code, IDs, and technical values
- Muted foreground color for secondary text (60–70% opacity or equivalent token)
- Minimal size variation — 3–4 sizes across the entire application
- Tight line heights (1.3–1.4) for UI, relaxed (1.5–1.6) for content areas
Building UI Typography Tokens
Structure your design system tokens to map directly to components:
:root {
/* Font sizes */
--font-size-xs: 0.6875rem; /* 11px */
--font-size-sm: 0.75rem; /* 12px */
--font-size-base: 0.875rem; /* 14px */
--font-size-lg: 1rem; /* 16px */
--font-size-xl: 1.125rem; /* 18px */
/* Font weights */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
/* Line heights */
--leading-tight: 1.25;
--leading-ui: 1.4;
--leading-content: 1.6;
/* Letter spacing */
--tracking-ui: 0.01em;
--tracking-button: 0.015em;
--tracking-caps: 0.05em;
/* Semantic aliases */
--text-label: var(--font-size-sm);
--text-body-ui: var(--font-size-base);
--text-body-content: var(--font-size-lg);
--text-heading: var(--font-size-xl);
}Map these tokens to components in your documentation:
| Component | Size Token | Weight Token | Leading Token |
|-----------|-----------|-------------|---------------|
| Button | --font-size-base | --font-weight-medium | --leading-tight |
| Input label | --text-label | --font-weight-medium | --leading-ui |
| Input value | --text-body-ui | --font-weight-normal | --leading-ui |
| Table header | --text-label | --font-weight-semibold | --leading-ui |
| Table cell | --text-body-ui | --font-weight-normal | --leading-ui |
| Card title | --font-size-lg | --font-weight-semibold | --leading-tight |
| Modal title | --font-size-xl | --font-weight-semibold | --leading-tight |
| Toast message | --font-size-sm | --font-weight-normal | --leading-ui |
| Tooltip | --font-size-xs | --font-weight-normal | --leading-tight |
Testing UI Typography
Validate your UI typography with these checks:
-
Squint test. Blur your eyes or zoom out to 50%. Can you still distinguish headings from body text, active from inactive states, and primary from secondary actions?
-
Fragment test. Read random UI labels and values out of context. Does "Account Settings" clearly communicate its function? Does "$1,240.00" read as a dollar amount, not a string?
-
Density test. Fill every component with maximum realistic content — long names, large numbers, multi-line descriptions. Does the typography hold or break?
-
Accessibility test. Verify all text meets WCAG AA contrast ratios (4.5:1 for normal text, 3:1 for large text). Test at 200% browser zoom. Confirm text reflows without loss of content or functionality.
UI typography is not glamorous work. It does not win design awards. But it is the typography users interact with most frequently — and the typography they notice most immediately when it fails. Build it systematically, tokenize it completely, and test it ruthlessly.