Design.dev design.dev

Typography for Web Design

Complete guide to web typography. Learn type scales, hierarchy, font selection and pairing, spacing, web fonts, variable fonts, responsive typography, and accessibility best practices.

Introduction

Typography is the art and technique of arranging type to make written language legible, readable, and appealing. On the web, good typography creates hierarchy, establishes tone, and guides users through content.

Core Typography Concepts

Legibility

How easily individual characters can be distinguished

Character recognition

Readability

How easily text can be read and understood

Content comprehension

Hierarchy

Visual order and importance of text elements

Content structure

Consistency

Uniform typography patterns throughout design

Design system

Key Principle: Typography should be invisible—users should read your content without noticing the typography itself. Good typography serves the content, never overshadows it.

Type Scale

A type scale is a progression of font sizes that creates visual hierarchy and consistency. Common scales use mathematical ratios.

Common Type Scale Ratios

Scale Name Ratio Example (16px base) Use Case
Minor Second 1.067 16, 17, 18, 19, 21, 22, 24 Subtle, tight spacing
Major Second 1.125 16, 18, 20, 23, 26, 29, 33 Conservative designs
Minor Third 1.2 16, 19, 23, 28, 33, 40, 48 Most versatile, common choice
Major Third 1.25 16, 20, 25, 31, 39, 49, 61 Clear hierarchy
Perfect Fourth 1.333 16, 21, 28, 37, 50, 67, 89 Bold, dramatic
Augmented Fourth 1.414 16, 23, 32, 45, 64, 91, 128 Very bold
Perfect Fifth 1.5 16, 24, 36, 54, 81, 122, 183 Strong contrast
Golden Ratio 1.618 16, 26, 42, 68, 110, 178, 288 Classic, harmonious

Creating Your Type Scale

Step Description Example
1. Choose base size Start with body text size (typically 16-18px) font-size: 16px;
2. Select ratio Pick a ratio that fits your design style 1.25 (Major Third)
3. Calculate sizes Multiply base by ratio for each step up 16 × 1.25 = 20px
4. Define scale Create 6-8 sizes from smallest to largest 12, 14, 16, 20, 25, 31, 39, 49
5. Name sizes Use semantic names or numbers xs, sm, base, lg, xl, 2xl, 3xl, 4xl

Tip: Use tools like Modular Scale or Type Scale to calculate and preview your scale.

Typography Hierarchy

Hierarchy guides readers through content by establishing importance and relationships between elements.

Heading Levels

Element Typical Size Weight Usage
<h1> 32-48px (2-3em) 700-900 Page title, one per page
<h2> 24-32px (1.5-2em) 600-800 Major sections
<h3> 20-24px (1.25-1.5em) 600-700 Subsections
<h4> 18-20px (1.125-1.25em) 600-700 Sub-subsections
<h5> 16-18px (1-1.125em) 600 Minor headings
<h6> 14-16px (0.875-1em) 600 Smallest headings

Body Text Styles

Element Size Weight Usage
Body Large 18-20px 400 Lead paragraphs, introductions
Body 16-18px 400 Main content, default text
Body Small 14-16px 400 Secondary content, captions
Label 12-14px 500-600 Form labels, UI labels
Caption 12-14px 400 Image captions, footnotes
Overline 10-12px 600-700 (uppercase) Eyebrows, categories

Creating Hierarchy

Technique How It Works CSS Example
Size Larger text draws more attention font-size: 2em;
Weight Bolder text appears more important font-weight: 700;
Color Higher contrast = more prominence color: #000; opacity: 0.9;
Spacing More space around = more importance margin: 2em 0 1em;
Case Uppercase for emphasis (sparingly) text-transform: uppercase;
Style Italic for emphasis or distinction font-style: italic;

Font Properties

Understanding CSS font properties is essential for controlling typography.

Font Size

Unit Description Example Best For
px Absolute pixels font-size: 16px; Precise control (not recommended for body text)
em Relative to parent font size font-size: 1.5em; Component-scoped typography
rem Relative to root font size font-size: 1.5rem; Most flexible, recommended
% Percentage of parent font-size: 150%; Proportional scaling
vw/vh Viewport width/height font-size: 5vw; Fluid typography
clamp() Responsive between min and max font-size: clamp(1rem, 2.5vw, 2rem); Responsive typography without media queries

Font Weight

Value Name Common Use
100 Thin Large display text only
200 Extra Light Large display text
300 Light Large body text, quotes
400 Normal/Regular Body text default
500 Medium Emphasis, labels, UI text
600 Semi Bold Subheadings, strong emphasis
700 Bold Headings, strong importance
800 Extra Bold Display headings
900 Black Extra heavy display text

Other Font Properties

Property Values Description
font-style normal, italic, oblique Text slant style
font-variant normal, small-caps Typographic variants
font-stretch condensed, normal, expanded Character width (variable fonts)
text-transform uppercase, lowercase, capitalize Case transformation
text-decoration underline, line-through, overline Text decoration lines
font-feature-settings OpenType features Advanced font features (ligatures, etc.)

Spacing & Vertical Rhythm

Proper spacing creates readability and visual harmony in typography.

Line Height (Leading)

Text Type Recommended Line Height CSS Example Reason
Body text (16-18px) 1.5-1.6 line-height: 1.5; Optimal readability for paragraphs
Large body (20px+) 1.4-1.5 line-height: 1.45; Slightly tighter for larger text
Small text (14px-) 1.6-1.8 line-height: 1.7; More space for legibility
Headings (large) 1.1-1.3 line-height: 1.2; Tighter for visual impact
Display text (huge) 1.0-1.1 line-height: 1.05; Very tight for hero text
Buttons/UI 1.0 line-height: 1; Precise vertical centering

Letter Spacing (Tracking)

Use Case Value CSS Example
Body text 0 letter-spacing: 0;
Large headings -0.02em to -0.04em letter-spacing: -0.02em;
Small caps 0.05em to 0.1em letter-spacing: 0.05em;
All caps 0.05em to 0.15em letter-spacing: 0.1em;
Small text (captions) 0.01em to 0.02em letter-spacing: 0.015em;

Measure (Line Length)

Metric Ideal Range CSS Example
Characters per line 45-75 (optimal: 66) max-width: 65ch;
Words per line 8-12 words max-width: 600px;
Wide content 75-90 characters max-width: 75ch;
Narrow content 35-45 characters max-width: 40ch;

Paragraph Spacing

Element Top Margin Bottom Margin CSS Example
Paragraphs 0 1em - 1.5em p { margin: 0 0 1.25em; }
Headings 1.5em - 2em 0.5em - 1em h2 { margin: 2em 0 0.75em; }
Lists 0 1em - 1.5em ul { margin: 0 0 1.5em; }
List items 0 0.25em - 0.5em li { margin-bottom: 0.5em; }

Rule of Thumb: Use ch units for max-width on text containers (1ch = width of the "0" character). This ensures consistent line lengths regardless of font choice.

Font Pairing

Combining fonts effectively creates contrast and hierarchy while maintaining harmony.

Font Pairing Principles

Principle Description Example
Contrast Pair fonts with distinct characteristics Serif heading + Sans-serif body
Harmony Fonts should share similar proportions or mood Both geometric or both humanist
Limit pairs Use 2-3 font families maximum One for headings, one for body
Same font family Use different weights and styles Roboto Light + Roboto Bold
Superfamilies Use fonts designed to work together Merriweather + Merriweather Sans

Classic Font Combinations

Headings Body Style Use Case
Playfair Display Source Sans Pro Elegant, editorial Magazines, blogs
Montserrat Merriweather Modern, readable Business, professional
Oswald Lato Bold, contemporary Marketing, landing pages
Raleway Open Sans Clean, minimalist Tech, startups
Poppins Inter Geometric, modern Apps, dashboards
Crimson Text Work Sans Classic, bookish Publishing, academia
Space Grotesk Space Mono Tech, futuristic Developer tools

Font Classification

Category Characteristics Examples Best For
Serif Small lines at letter ends, traditional Georgia, Times, Merriweather Long-form reading, print feel
Sans Serif Clean, no decorative strokes Arial, Helvetica, Inter UI, screens, modern designs
Slab Serif Thick, blocky serifs Rockwell, Courier, Roboto Slab Headings, mechanical feel
Monospace Fixed-width characters Courier, Consolas, Fira Code Code, technical content
Display Decorative, attention-grabbing Lobster, Bebas Neue Headings, logos (use sparingly)
Handwriting Script or casual writing style Pacifico, Dancing Script Accents, signatures

Web Fonts

Web fonts allow you to use custom typefaces beyond system fonts. Understanding loading and implementation is crucial.

Font Sources

Source Pros Cons Best For
Google Fonts Free, easy, CDN-hosted, variable fonts Privacy concerns, limited selection Most projects, quick starts
Adobe Fonts High quality, large library, sync to desktop Requires Creative Cloud subscription Professional design work
Self-hosted Full control, privacy, performance tuning More setup, need to manage updates Production apps, GDPR compliance
System fonts Zero load time, familiar to users Limited variety, platform differences Performance-critical apps
Font marketplaces Unique typefaces, commercial licenses Cost, licensing complexity Branding, unique identity

@font-face Syntax

Property Description Example
font-family Name you'll use to reference the font font-family: 'My Font';
src Path to font files (woff2, woff, ttf) src: url('font.woff2') format('woff2');
font-weight Weight this file represents font-weight: 400;
font-style Style this file represents font-style: normal;
font-display How font loads (swap, block, fallback, optional) font-display: swap;
unicode-range Character range to use this font for unicode-range: U+0000-00FF;

Font File Formats

Format Browser Support File Size Recommendation
WOFF2 All modern browsers (96%+) Smallest (30% smaller than WOFF) ✓ Use first, best compression
WOFF All browsers (98%+) Small ✓ Use as fallback for old browsers
TTF/OTF Universal Large, uncompressed Use for development only
EOT IE 6-11 only Large Obsolete, skip unless supporting IE
SVG Legacy Safari Very large Obsolete, not recommended

System Font Stack

Stack Type CSS
System UI font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
Serif font-family: Georgia, Cambria, "Times New Roman", Times, serif;
Sans Serif font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
Monospace font-family: "SF Mono", Monaco, "Cascadia Code", "Courier New", monospace;

Variable Fonts

Variable fonts contain multiple variations in a single file, offering flexibility and better performance.

Variable Font Axes

Axis CSS Property Description Typical Range
Weight font-weight Thickness of strokes 100-900
Width font-stretch Horizontal compression/expansion 50%-200%
Slant font-style: oblique [angle] Angle of text slant -20deg to 20deg
Optical Size font-optical-sizing Optimizations for different sizes 6pt-72pt
Italic font-style: italic Upright to italic 0-1

Custom Axes (font-variation-settings)

Example Axis Tag CSS
Grade GRAD font-variation-settings: 'GRAD' 50;
Casual CASL font-variation-settings: 'CASL' 1;
Cursive CRSV font-variation-settings: 'CRSV' 0.5;
Monospace MONO font-variation-settings: 'MONO' 1;

Variable Font Benefits

Benefit Description Example
File size One file instead of multiple weights Inter: 1 variable file vs 18 static files
Flexibility Any value on axis, not just predefined weights font-weight: 450; (not just 400 or 500)
Animation Smooth transitions between variations Animate weight on hover
Responsive Adjust font characteristics at different sizes Optical sizing for better legibility

Popular Variable Fonts

Font Axes Source Best For
Inter Weight, Slant Google Fonts UI, body text
Roboto Flex Weight, Width, Optical Size, Grade Google Fonts Versatile, UI
Source Sans 3 Weight, Width Adobe Fonts Body text, professional
Recursive Weight, Slant, Casual, Monospace Google Fonts Code, playful designs
Amstelvar 14 axes Google Fonts Experimentation, display

Browser Support: Variable fonts are supported in all modern browsers (95%+). Always provide a fallback for older browsers.

Font Loading Strategies

How fonts load affects performance and user experience. Choose the right strategy for your use case.

font-display Values

Value Behavior Use Case Trade-offs
swap Show fallback immediately, swap when loaded Most websites (recommended) Brief flash of unstyled text (FOUT)
block Hide text briefly (~3s), then show font or fallback Icon fonts, critical branding Invisible text delay (FOIT)
fallback Very brief hide (~100ms), swap if loaded within 3s Balance between swap and block May not swap if slow connection
optional Very brief hide, browser decides whether to swap Performance-critical, fonts are enhancement Font may not load on slow connections
auto Browser chooses (usually similar to block) Default, not recommended Unpredictable behavior

Loading Strategies

Strategy Implementation When to Use
Preload critical fonts <link rel="preload" href="font.woff2" as="font" crossorigin> Above-the-fold text, critical headings
Subset fonts Include only needed characters/glyphs Reduce file size, faster loading
Font loading API document.fonts.load('16px My Font') Advanced control, custom loading UI
CDN with cache Use Google Fonts CDN or similar Quick implementation, shared cache
Self-host with caching Host fonts locally with long cache headers Best performance, privacy, control

Performance Optimization

Technique How It Helps Implementation
Limit font weights Fewer files to download Use only 2-3 weights (400, 600, 700)
Use WOFF2 only Smallest file size, modern browsers src: url('font.woff2') format('woff2');
Unicode subsetting Remove unused characters Tools: glyphhanger, Font Squirrel
Optimize fallback fonts Reduce layout shift Match x-height, width with size-adjust
Use variable fonts One file instead of multiple Replace multiple static weights
Lazy load fonts Load fonts when needed Load display fonts for below-fold content later

Best Practice: Use font-display: swap for most cases. Preload your most critical font file. Self-host fonts when possible for better performance and privacy.

Responsive Typography

Typography should adapt to different screen sizes and reading contexts.

Responsive Font Sizing Techniques

Technique CSS Example Pros Cons
Media queries @media (min-width: 768px) { h1 { font-size: 3rem; } } Precise control, reliable More code, breakpoint-dependent
Viewport units font-size: 5vw; Fluid scaling Can be too small/large, accessibility issues
clamp() font-size: clamp(1rem, 2.5vw, 3rem); Fluid with limits, no media queries needed Requires modern browser
calc() + vw font-size: calc(1rem + 1vw); Fluid with base size No max/min constraints
Container queries @container (min-width: 400px) { ... } Component-based responsive Newer, limited support

Fluid Typography Formula

Use Case clamp() Example Result
Body text font-size: clamp(1rem, 0.875rem + 0.5vw, 1.125rem); 16px → 18px (scales between)
H1 heading font-size: clamp(2rem, 1.5rem + 2vw, 4rem); 32px → 64px
H2 heading font-size: clamp(1.5rem, 1.25rem + 1.5vw, 3rem); 24px → 48px
Small text font-size: clamp(0.875rem, 0.875rem + 0.25vw, 1rem); 14px → 16px

Responsive Spacing

Property Mobile Desktop Fluid Example
Line height 1.6-1.8 1.5-1.6 Usually fixed value
Paragraph spacing 1.25em 1.5em margin-bottom: clamp(1.25rem, 1rem + 1vw, 1.5rem);
Heading spacing 1.5em top 2em top margin-top: clamp(1.5rem, 1rem + 2vw, 2.5rem);
Max width 100% 65ch max-width: min(65ch, 100%);

Mobile Typography Considerations

Consideration Recommendation Why
Minimum font size 16px for body text Prevents mobile zoom on form inputs
Line length 45-60 characters Shorter lines for narrow screens
Tap targets 44-48px minimum Easy tapping for links in text
Line height Slightly larger (1.6-1.8) Easier reading on small screens
Font weight Avoid very light weights Harder to read on small screens

Typography Accessibility

Accessible typography ensures content is readable for all users, including those with visual impairments.

Minimum Requirements

Requirement WCAG Level Guideline
Minimum font size AA 16px for body text (14px acceptable for large sites)
Color contrast (normal text) AA 4.5:1 ratio minimum
Color contrast (large text) AA 3:1 ratio (18px+ or 14px+ bold)
Color contrast (enhanced) AAA 7:1 for normal, 4.5:1 for large
Text resize AA Text must scale up to 200% without loss of content
Line spacing AA At least 1.5 for paragraphs
Paragraph spacing AA At least 2× font size

Readable Typography Checklist

Aspect Guideline Why It Matters
Font size 16px minimum for body Prevents mobile zoom, readable for most users
Line height 1.5-1.6 for body text Easier to track lines, helps dyslexic readers
Line length 45-75 characters Optimal reading comfort, reduces eye strain
Alignment Left-aligned (for LTR languages) Easier to find next line, helps dyslexic readers
Justification Avoid full justification Uneven spacing creates "rivers" that hinder reading
All caps Use sparingly, never for long text Harder to read, loses word shape recognition
Italics Short phrases only Extended italics harder to read
Link underlines Underline or clear visual distinction Color alone insufficient for color-blind users

Dyslexia-Friendly Typography

Guideline Recommendation
Font choice Sans-serif fonts with distinct letterforms (Verdana, Arial, Comic Sans)
Letter spacing Slightly increased: letter-spacing: 0.12em;
Word spacing Slightly increased: word-spacing: 0.16em;
Line height 1.5-1.8 (more generous)
Paragraph spacing 1.5-2× line height
Text alignment Left-aligned, ragged right (never justified)
Line length 60-70 characters (slightly shorter)

Accessibility Tip: Never rely on color alone to convey meaning. Always use additional cues like font weight, underlines, or icons. Test your typography with actual users who have visual impairments.

Best Practices & Common Mistakes

Do's

✓ Use rem for font sizes

Respects user preferences, scales consistently

font-size: 1.5rem;

✓ Establish type scale

Creates consistent, harmonious hierarchy

16, 20, 25, 31, 39, 49

✓ Limit font families

2-3 max for cohesive design

One for headings, one for body

✓ Use font-display: swap

Shows content immediately with fallback

font-display: swap;

✓ Test at different sizes

Ensure readability on all devices

Mobile, tablet, desktop

✓ Check color contrast

Minimum 4.5:1 for body text

Use contrast checker tool

✓ Set max-width on text

Optimal line length for readability

max-width: 65ch;

✓ Use system fonts when appropriate

Zero load time, better performance

-apple-system, BlinkMacSystemFont

Don'ts

✗ Don't use px for font sizes

Doesn't respect user preferences

Instead: Use rem or em

✗ Don't use too many fonts

Slows loading, creates visual chaos

Instead: Limit to 2-3 families

✗ Don't use font-weight: normal/bold

Vague, depends on browser defaults

Instead: Use numeric values (400, 700)

✗ Don't justify body text

Creates uneven spacing, rivers of white

Instead: Left-align for readability

✗ Don't use long lines

Hard to track, eye strain

Instead: 45-75 characters per line

✗ Don't use font size < 16px

Hard to read, triggers mobile zoom

Instead: 16px minimum for body

✗ Don't use all caps for long text

Significantly harder to read

Instead: Use for short labels only

✗ Don't rely on color alone

Excludes color-blind users

Instead: Add underlines, icons, or weight

✗ Don't use tight line-height on body

Lines too close together

Instead: Use 1.5-1.6 for paragraphs

✗ Don't load unnecessary font weights

Slows page load

Instead: Load only weights you use

Golden Rule: Typography should be invisible. When done right, users focus on content, not the type itself. Prioritize readability over creativity.