# 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');
});
```