# Typography Reference ## Table of Contents 1. Font Pairing Strategies 2. Type Scale Systems 3. CSS Typography Techniques 4. Variable Fonts 5. Font Loading Optimization --- ## 1. Font Pairing Strategies ### The Contrast Principle Great pairings create tension through contrast in one dimension while maintaining harmony in others. **Contrast Dimensions:** - Weight (light vs. bold) - Width (condensed vs. extended) - Style (serif vs. sans) - Era (classic vs. contemporary) - Mood (serious vs. playful) ### Proven Pairings by Style **Editorial/Magazine:** ``` Display: Freight Display / Editorial New / Canela Body: Söhne / Untitled Sans / Graphik ``` **Tech/Modern:** ``` Display: Monument Extended / ABC Favorit Extended / Druk Wide Body: Inter (only acceptable here) / Suisse Int'l / Neue Montreal ``` **Luxury/Fashion:** ``` Display: Didot / Romana / Noe Display Body: Apercu / Basis Grotesque / Plain ``` **Brutalist/Raw:** ``` Display: ABC Diatype / Neue Haas Grotesk / Helvetica Now Body: Same as display (mono-font strategy) ``` **Creative/Playful:** ``` Display: Basement Grotesque / GT Maru / Gambarino Body: GT Walsheim / Gilroy / Proxima Nova ``` ### Free/Google Font Alternatives **Premium Feel, Zero Cost:** ``` Display Options: ├── Space Grotesk (geometric, techy) ├── Instrument Serif (editorial elegance) ├── Fraunces (variable, characterful) ├── Playfair Display (classic serif) ├── Cormorant Garamond (refined serif) └── Syne (bold, distinctive) Body Options: ├── Plus Jakarta Sans (clean, modern) ├── DM Sans (geometric, friendly) ├── Outfit (variable, versatile) ├── Satoshi (via Fontshare - free!) └── General Sans (via Fontshare) ``` --- ## 2. Type Scale Systems ### Fluid Typography (Preferred) ```css /* Fluid scale using clamp() */ :root { /* Base: 16px at 320px → 20px at 1440px */ --text-base: clamp(1rem, 0.857rem + 0.714vw, 1.25rem); /* Scale ratio: 1.25 (Major Third) */ --text-sm: clamp(0.8rem, 0.686rem + 0.571vw, 1rem); --text-lg: clamp(1.25rem, 1.071rem + 0.893vw, 1.563rem); --text-xl: clamp(1.563rem, 1.339rem + 1.116vw, 1.953rem); --text-2xl: clamp(1.953rem, 1.674rem + 1.395vw, 2.441rem); --text-3xl: clamp(2.441rem, 2.092rem + 1.744vw, 3.052rem); --text-4xl: clamp(3.052rem, 2.616rem + 2.18vw, 3.815rem); --text-5xl: clamp(3.815rem, 3.27rem + 2.725vw, 4.768rem); /* Hero sizes - dramatic scale */ --text-hero: clamp(4rem, 2rem + 8vw, 12rem); --text-display: clamp(3rem, 1.5rem + 6vw, 9rem); } ``` ### Step-Based Scale (Fixed Breakpoints) ```css /* Mobile-first scale */ :root { --step--2: 0.75rem; /* 12px */ --step--1: 0.875rem; /* 14px */ --step-0: 1rem; /* 16px - base */ --step-1: 1.125rem; /* 18px */ --step-2: 1.5rem; /* 24px */ --step-3: 2rem; /* 32px */ --step-4: 3rem; /* 48px */ --step-5: 4rem; /* 64px */ --step-6: 6rem; /* 96px */ --step-7: 8rem; /* 128px */ } @media (min-width: 768px) { :root { --step-4: 4rem; --step-5: 6rem; --step-6: 9rem; --step-7: 12rem; } } @media (min-width: 1280px) { :root { --step-5: 8rem; --step-6: 12rem; --step-7: 16rem; } } ``` --- ## 3. CSS Typography Techniques ### Tracking (Letter-Spacing) ```css /* Tracking scales inversely with size */ .text-hero { letter-spacing: -0.04em; /* Tight for massive text */ } .text-display { letter-spacing: -0.03em; } .text-heading { letter-spacing: -0.02em; } .text-body { letter-spacing: 0; /* Normal for body */ } .text-small { letter-spacing: 0.01em; /* Slightly open for small text */ } .text-caps { letter-spacing: 0.1em; /* Open for all-caps */ text-transform: uppercase; } ``` ### Leading (Line-Height) ```css /* Line-height based on use case */ .leading-hero { line-height: 0.9; /* Very tight for impact */ } .leading-display { line-height: 1.0; } .leading-heading { line-height: 1.1; } .leading-body { line-height: 1.6; /* Comfortable reading */ } .leading-relaxed { line-height: 1.8; /* Long-form content */ } ``` ### Advanced Techniques ```css /* Optical margin alignment */ .hanging-punctuation { hanging-punctuation: first last; } /* Font feature settings */ .tabular-nums { font-variant-numeric: tabular-nums; } .oldstyle-nums { font-variant-numeric: oldstyle-nums; } .ligatures { font-variant-ligatures: common-ligatures discretionary-ligatures; } /* Text rendering optimization */ .hero-text { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* Preventing text wrapping issues */ .no-orphans { text-wrap: balance; /* Modern browsers */ } /* Hyphenation for justified text */ .justified { text-align: justify; hyphens: auto; hyphenate-limit-chars: 6 3 2; } ``` ### Text Masking & Gradient Text ```css /* Gradient text */ .gradient-text { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } /* Image-filled text */ .image-text { background-image: url('/texture.jpg'); background-size: cover; -webkit-background-clip: text; -webkit-text-fill-color: transparent; } /* Animated gradient text */ .animated-gradient-text { background: linear-gradient(90deg, #ff0000, #00ff00, #0000ff, #ff0000); background-size: 300% 100%; -webkit-background-clip: text; -webkit-text-fill-color: transparent; animation: gradient-shift 8s ease infinite; } @keyframes gradient-shift { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } } ``` --- ## 4. Variable Fonts ### Benefits - Single file, multiple weights/widths - Fluid animations between weights - Smaller total file size ### Implementation ```css /* Loading variable font */ @font-face { font-family: 'Inter'; src: url('/fonts/Inter-Variable.woff2') format('woff2-variations'); font-weight: 100 900; font-display: swap; } /* Using weight axis */ .light { font-variation-settings: 'wght' 300; } .regular { font-variation-settings: 'wght' 400; } .medium { font-variation-settings: 'wght' 500; } .bold { font-variation-settings: 'wght' 700; } .black { font-variation-settings: 'wght' 900; } /* Animating weight */ .hover-weight { font-variation-settings: 'wght' 400; transition: font-variation-settings 0.3s ease; } .hover-weight:hover { font-variation-settings: 'wght' 700; } /* Multiple axes */ .variable-text { font-variation-settings: 'wght' 500, /* Weight */ 'wdth' 100, /* Width */ 'ital' 0, /* Italic */ 'slnt' 0; /* Slant */ } ``` --- ## 5. Font Loading Optimization ### Critical Font Strategy ```html ``` ### Font Subsetting ```bash # Using pyftsubset to create subset pyftsubset "Font.ttf" \ --output-file="Font-subset.woff2" \ --flavor=woff2 \ --layout-features="kern,liga,calt" \ --unicodes="U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD" ``` ### FOUT/FOIT Prevention ```css /* Font loading classes via JavaScript */ .fonts-loading { /* Use fallback stack */ font-family: Georgia, serif; } .fonts-loaded .body-text { font-family: 'Custom Font', Georgia, serif; } /* Or use font-display */ @font-face { font-family: 'Display Font'; src: url('/fonts/display.woff2') format('woff2'); font-display: swap; /* Show fallback immediately, swap when loaded */ } @font-face { font-family: 'Body Font'; src: url('/fonts/body.woff2') format('woff2'); font-display: optional; /* Only use if already cached */ } ``` ### JavaScript Font Loading API ```javascript // Check if fonts are loaded document.fonts.ready.then(() => { document.documentElement.classList.add('fonts-loaded'); }); // Load specific font const font = new FontFace('Display', 'url(/fonts/display.woff2)'); font.load().then((loadedFont) => { document.fonts.add(loadedFont); document.body.classList.add('display-font-loaded'); }); ```