Copy. Paste. Ship.
Ready-to-use CSS and Google Fonts embed code for your project.
62+ curated Google Fonts
Hand-picked for quality. Classified for intelligent pairing.
- Playfair DisplaySerif
- MerriweatherSerif
- LoraSerif
- EB GaramondSerif
- Cormorant GaramondSerif
- Crimson TextSerif
- SpectralSerif
- Libre BaskervilleSerif
- PT SerifSerif
- BitterSerif
- Roboto SerifSerif
- Noto SerifSerif
- GelasioSerif
- Frank Ruhl LibreSerif
- VollkornSerif
- InterSans
- RobotoSans
- Open SansSans
- LatoSans
- NunitoSans
- Nunito SansSans
- Source Sans 3Sans
- PoppinsSans
- RalewaySans
- MontserratSans
- Work SansSans
- KarlaSans
- DM SansSans
- FigtreeSans
- ManropeSans
- Plus Jakarta SansSans
- IBM Plex SansSans
- BarlowSans
- EpilogueSans
- SoraSans
- Abril FatfaceDisplay
- AntonDisplay
- Bebas NeueDisplay
- OswaldDisplay
- Fjalla OneDisplay
- Josefin SansDisplay
- Big Shoulders DisplayDisplay
- RighteousDisplay
- Alfa Slab OneDisplay
- CardoSerif
- CinzelDisplay
- Poiret OneDisplay
- Permanent MarkerDisplay
- PacificoDisplay
- JetBrains MonoMono
- Fira CodeMono
- Source Code ProMono
- Roboto MonoMono
- Space MonoMono
- Courier PrimeMono
- IBM Plex MonoMono
- InconsolataMono
- Dancing ScriptScript
- CaveatScript
- Indie FlowerScript
- SatisfyScript
- YellowtailScript
Playfair Display
Elegant · Editorial · Classic Serif
The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump. Sphinx of black quartz, judge my vow. Two driven jocks help fax my big quiz.
Web font loading, fallback stacks, and CSS typography snippets
The tool above hands you a font trio plus the Google Fonts embed and the font-family declarations to drop into a stylesheet. The reference below covers the surrounding code you write once and rarely touch again: the four ways to load a web font, what each font-display value does, fallback stacks that match each classification, size-adjusted metric overrides, and the typography token shapes that hold up across product UIs and marketing pages.
Loading Google Fonts: four embed patterns
<!-- 1. Link tag in <head>, the default Google Fonts copy-paste -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet">/* 2. CSS @import (slower; blocks the stylesheet until fetched) */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&family=Playfair+Display:wght@700&display=swap');<!-- 3. Preload + link, for critical-render-path optimization -->
<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap">/* 4. Self-hosted @font-face (one HTTP origin, no third-party request) */
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400 700;
font-display: swap;
src: url('/fonts/inter-variable.woff2') format('woff2-variations');
}Which pattern fits which project:
| Pattern | Best when | Trade-off |
|---|---|---|
| Link tag | Default, no special constraints | One extra DNS handshake to fonts.gstatic.com |
@import in CSS | Adding fonts to a stylesheet you can edit but not the HTML | Blocks downstream CSS parsing until the request resolves |
| Preload + link | First Contentful Paint is your priority metric | Slight memory overhead from holding the font in cache earlier |
| Self-hosted | Privacy strictness, single-origin caching, offline builds | You take on font subsetting and update cadence yourself |
font-display strategies
The font-display descriptor controls what the browser shows between page render and web-font arrival. Five values, ordered by how aggressively they reveal the real font:
| Value | Block period | Swap period | Behavior |
|---|---|---|---|
| auto | up to 3s | infinite | Browser default; usually behaves like block |
| block | up to 3s | infinite | Invisible text, then swap to web font (FOIT) |
| swap | 0ms | infinite | Fallback first, then swap (FOUT). Google Fonts default. |
| fallback | ~100ms | ~3s | Tiny FOIT, then fallback, then web font if it arrives in time |
| optional | ~100ms | 0 | Tiny FOIT, then the fallback is locked in for the session |
@font-face { font-family: 'Inter'; font-display: swap; src: url('/fonts/inter.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-display: fallback; src: url('/fonts/inter.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-display: optional; src: url('/fonts/inter.woff2') format('woff2'); }Rule of thumb: marketing pages choose swap (the correct font matters more than reflow). Product UIs and dashboards choose optional (no layout jump matters more than the right font appearing).
System fallback stacks by classification
The fallback chain is what the browser shows while the web font is downloading, plus what it falls back to permanently if the request fails. A good chain has similar metrics (x-height, average advance width) to the web font, so layout barely shifts when the swap happens.
/* Humanist sans (Inter, Source Sans 3, Open Sans, Lato) */
font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
/* Geometric sans (Montserrat, Poppins, Work Sans, Raleway) */
font-family: 'Montserrat', 'Avenir Next', Avenir, 'Trebuchet MS', sans-serif;
/* Transitional serif (Playfair Display, Cormorant, EB Garamond) */
font-family: 'Playfair Display', Georgia, Cambria, 'Times New Roman', Times, serif;
/* Humanist serif (Lora, Spectral, Source Serif 4) */
font-family: 'Lora', 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
/* Slab serif (Roboto Slab, Zilla Slab, Bitter, Merriweather) */
font-family: 'Roboto Slab', Rockwell, 'Courier Bold', Courier, Georgia, serif;
/* Monospace (JetBrains Mono, Fira Code, Source Code Pro, DM Mono) */
font-family: 'JetBrains Mono', 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;Match the fallback to the web font's classification, not to its mood or vibe. A geometric sans paired with Georgia as a fallback will reflow visibly the moment the swap happens, even though Georgia happens to be a respectable typeface in its own right.
size-adjust and ascent-override for stable swaps
When font-display: swap produces a layout shift you can't tolerate, normalize the fallback's metrics so the swap stays visually flat:
@font-face {
font-family: 'Inter Fallback';
src: local('Arial');
size-adjust: 107.4%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
body {
font-family: 'Inter', 'Inter Fallback', sans-serif;
}The four descriptors stretch and shift the local fallback so its line box matches the web font's. Tools like fontpie (CLI) and Capsize (web UI) calculate these numbers automatically per font pair, so you rarely write them by hand.
Weight numbers and what they mean
/* Variable font, one declaration covers the full axis */
font-weight: 350;
/* Static fonts use the nine canonical weights */
font-weight: 100; /* Thin */
font-weight: 200; /* Extra Light */
font-weight: 300; /* Light */
font-weight: 400; /* Regular (default) */
font-weight: 500; /* Medium */
font-weight: 600; /* Semi Bold */
font-weight: 700; /* Bold */
font-weight: 800; /* Extra Bold */
font-weight: 900; /* Black */Default heading/body weight pairings the curated library tends to recommend:
| Family | Heading weight | Body weight |
|---|---|---|
| Inter (variable) | 700 | 400 |
| Playfair Display | 700 | (heading-only family) |
| Montserrat | 700 or 800 | 400 |
| Lora | 600 | 400 |
| Source Sans 3 | 700 | 400 |
| Roboto Slab | 700 | 400 |
When a family ships only two weights, the gap between heading and body is fixed. When it ships the full axis (Inter goes 100–900), pick the gap intentionally: 700/400 is the safe default; 600/400 reads as editorial; 800/400 is the high-impact marketing hero.
Typography custom properties pattern
:root {
--font-display: 'Playfair Display', Georgia, serif;
--font-body: 'Inter', system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', Menlo, monospace;
--size-base: 1rem;
--size-step: 1.25; /* major third, editorial */
--size-xs: calc(var(--size-base) / var(--size-step));
--size-sm: var(--size-base);
--size-md: calc(var(--size-base) * var(--size-step));
--size-lg: calc(var(--size-md) * var(--size-step));
--size-xl: calc(var(--size-lg) * var(--size-step));
--size-2xl: calc(var(--size-xl) * var(--size-step));
--line-tight: 1.2;
--line-base: 1.55;
--line-loose: 1.75;
}
h1 { font-family: var(--font-display); font-size: var(--size-2xl); line-height: var(--line-tight); }
h2 { font-family: var(--font-display); font-size: var(--size-xl); line-height: var(--line-tight); }
p { font-family: var(--font-body); font-size: var(--size-md); line-height: var(--line-base); }
code { font-family: var(--font-mono); }Modular-scale ratios worth memorizing:
| Ratio | Name | Feels like |
|---|---|---|
| 1.067 | Minor second | Cramped, barely a step |
| 1.125 | Major second | Subtle, dense documentation |
| 1.200 | Minor third | Default for product UIs |
| 1.250 | Major third | Editorial, magazine |
| 1.333 | Perfect fourth | Marketing-heavy, dramatic |
| 1.414 | Augmented fourth | Very large headlines |
| 1.500 | Perfect fifth | Hero-only territory |
Tailwind typography config
Tailwind v3 (tailwind.config.js):
module.exports = {
theme: {
extend: {
fontFamily: {
display: ['Playfair Display', 'Georgia', 'serif'],
body: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'Menlo', 'monospace'],
},
fontSize: {
'display-2xl': ['4.5rem', { lineHeight: '1.1', fontWeight: '700' }],
'display-xl': ['3.75rem', { lineHeight: '1.15', fontWeight: '700' }],
'display-lg': ['3rem', { lineHeight: '1.2', fontWeight: '700' }],
},
},
},
}<h1 className="font-display text-display-xl">The weight of words</h1>
<p className="font-body text-base">Body copy with humanist-sans warmth.</p>Tailwind v4 (CSS-first config) puts the same tokens in an @theme block:
@theme {
--font-display: 'Playfair Display', Georgia, serif;
--font-body: 'Inter', system-ui, sans-serif;
--text-display-xl: 3.75rem;
--text-display-xl--line-height: 1.15;
--text-display-xl--font-weight: 700;
}Common gotchas
| Symptom | Cause | Fix |
|---|---|---|
| Text jumps when the web font loads | Fallback metrics don't match the web font | Add a @font-face block with size-adjust, ascent-override, descent-override |
| Bold text renders as fake-bold (synthesized) | The 700 weight wasn't loaded | Add &wght@400;700 to the Google Fonts URL; verify in DevTools' Computed panel |
| Italic looks slanted, not designed | Italic variant wasn't loaded | Add ital@0;1 to the URL: Inter:ital,wght@0,400;1,400 |
| Invisible text for 3 seconds | font-display: block (or auto, which acts like block on some browsers) | Switch to font-display: swap for marketing, optional for product UI |
| Headline reflows after fonts load | No fallback metric tuning | Use local() fallback with size-adjust, or use font-display: optional to lock fallback |
| CLS score above 0.1 | Web font swap causing layout shift | Preload the font OR set font-display: optional OR tune fallback metrics |
| Self-hosted woff2 doesn't load | Wrong MIME type | Set Content-Type: font/woff2; Cloudflare R2 sets this automatically, raw S3 does not |
| Variable font weights ignored | Declared as a static font with a single weight | Use font-weight: 100 900 in @font-face and format('woff2-variations') in src |
| Google Fonts URL is hundreds of characters | Loading every weight and style | Trim to only the weights you actually use; DevTools' Coverage tab shows what was applied |
Related concepts
- Cumulative Layout Shift (CLS).
- Google's Core Web Vitals metric most affected by font swaps. Late-arriving fonts that reflow text are the single most common cause of CLS on content sites.
- Variable fonts.
- A single file containing a continuous range of weights, widths, and other axes; replaces six or more static files for the same family.
local()in @font-face.- References a font already installed on the user's system, skipping the network entirely when the family is common (Arial, Georgia, Helvetica).
unicode-rangesubsetting.- Splits a font into character ranges so the browser only downloads what the page actually renders. Google Fonts ships these subsets by default.
- font-feature-settings.
- OpenType features (tabular numerals, ligatures, stylistic sets, small caps) exposed as CSS properties for fine-grained typographic control.