Tailwind CSS Custom Fonts — Adding Google Fonts and Web Fonts
In this tutorial, you will learn about Tailwind CSS Custom Fonts. We cover key concepts, practical examples, and best practices to help you master this topic.
Tailwind CSS custom fonts are added by importing web fonts (Google Fonts, Adobe Fonts, or self-hosted), then registering them in the fontFamily theme configuration for utility class use.
What You'll Learn
You will learn how to import Google Fonts, self-host web fonts, configure custom font families in the config, apply them with font-* utilities, and manage font loading.
Why It Matters
Typography defines brand identity. DodaTech uses custom fonts across all products -- Inter for UI, Source Sans Pro for documentation -- configured once in Tailwind and used globally.
Real-World Use
Doda Browser uses Inter (sans-serif) for UI elements and JetBrains Mono for code snippets, both configured in tailwind.config.js as font-body and font-mono families.
flowchart LR
A[Dark Mode] --> B[Custom Fonts]
B --> C[Google Fonts]
B --> D[Self-Hosted]
B --> E[Config]
B --> F[Loading]
style B fill:#38bdf8,stroke:#0284c7,color:#fff
style C fill:#22c55e,stroke:#16a34a,color:#fff
Google Fonts Setup
<!-- Step 1: Add to HTML head -->
<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;500;600;700&family=Playfair+Display:wght@700&display=swap" rel="stylesheet">
// Step 2: Configure in tailwind.config.js
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
display: ['Playfair Display', 'serif'],
},
},
},
}
<!-- Step 3: Use in HTML -->
<p class="font-sans text-base text-gray-700">
Body text using Inter (sans-serif).
</p>
<h1 class="font-display text-4xl text-gray-900">
Heading using Playfair Display.
</h1>
Expected output: Body text renders in Inter, headings in Playfair Display. Both fonts load from Google Fonts with swap display Strategy.
Self-Hosted Fonts
/* Step 1: Add to your main CSS file */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom-font.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom-font-bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
// Step 2: Configure in tailwind.config.js
module.exports = {
theme: {
extend: {
fontFamily: {
custom: ['CustomFont', 'sans-serif'],
},
},
},
}
<!-- Step 3: Use the font -->
<p class="font-custom text-lg font-bold">
Text in self-hosted custom font.
</p>
Expected output: Text renders in the self-hosted font with fallback to sans-serif. The woff2 format provides modern browser compression.
Multiple Font Families
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
serif: ['Merriweather', 'Georgia', 'serif'],
mono: ['JetBrains Mono', 'Fira Code', 'monospace'],
display: ['Playfair Display', 'serif'],
body: ['Source Sans Pro', 'sans-serif'],
},
},
},
}
<div class="space-y-4 p-4">
<p class="font-sans text-lg">font-sans: Inter (system-ui fallback)</p>
<p class="font-serif text-lg">font-serif: Merriweather (Georgia fallback)</p>
<p class="font-mono text-lg">font-mono: JetBrains Mono (Fira Code fallback)</p>
<p class="font-display text-lg">font-display: Playfair Display</p>
<p class="font-body text-lg">font-body: Source Sans Pro</p>
</div>
Expected output: Five different font families applied via utility classes, each with appropriate fallbacks.
Font Loading Strategy
<!-- Preloading critical fonts -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<!-- Using font-display: swap -->
<style>
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2');
font-display: swap; /* Shows fallback immediately, swaps when loaded */
}
</style>
<!-- FOUT (Flash of Unstyled Text) management -->
<div class="text-gray-900">
<p class="invisible font-loaded:visible">
Text hidden until font loads (prevents FOUT).
</p>
</div>
Expected output: With font-display: swap, text is visible in fallback font immediately and swaps to the custom font when loaded, preventing invisible text.
Custom Font with Weights
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
fontWeight: {
thin: '100',
extralight: '200',
light: '300',
normal: '400',
medium: '500',
semibold: '600',
bold: '700',
extrabold: '800',
black: '900',
},
},
},
}
<div class="font-sans space-y-1">
<p class="font-thin">font-thin (100) - requires Thin weight</p>
<p class="font-light">font-light (300) - requires Light weight</p>
<p class="font-normal">font-normal (400) - Regular</p>
<p class="font-medium">font-medium (500) - Medium</p>
<p class="font-semibold">font-semibold (600) - Semibold</p>
<p class="font-bold">font-bold (700) - Bold</p>
</div>
Expected output: Different font weights applied. Ensure the font file includes all requested weights; missing weights fall back to the closest available.
Common Mistakes
1. Not Preconnecting to Google Fonts
Without preconnect links, the browser delays connecting to Google's servers, increasing perceived load time.
2. Using Too Many Font Weights
Each weight adds 100-300KB. Only include the weights you actually use. Too many weights bloat the page.
3. Not Setting Fallback Fonts
Without fallbacks, custom font failure leaves unstyled text. Always include system fallbacks like sans-serif, serif, or monospace.
4. Forgetting font-display: swap
Without swap, the browser may hide text for up to 3 seconds while the font loads, causing invisible text.
5. Importing Fonts in CSS Instead of HTML
CSS @import blocks rendering. Use HTML link tags with preconnect for faster font loading.
Practice Questions
Where do you register custom font families? In tailwind.config.js under theme.extend.fontFamily.
How do you prevent invisible text while fonts load? Use
font-display: swapin @font-face or the Google Fonts &display=swap parameter.What is the benefit of preconnect? It establishes an early connection to the font server, reducing font loading latency.
How many font families can you configure? As many as needed. Each key becomes a font-{name} utility class.
What format is recommended for self-hosted fonts? WOFF2 for best compression. Fall back to WOFF for older browser support.
Challenge
Set up a project with 3 custom fonts: Inter for body text (400, 500, 600, 700), Playfair Display for headings (700), and JetBrains Mono for code (400, 700). Configure all in the Tailwind config and use them.
FAQ
Mini Project
Build a typography showcase page with 3 font families: a display font for hero headings, a sans-serif for body text, and a monospace font for code snippets. Include responsive text sizes and proper font loading optimization.
What's Next
Now master Custom Colors for brand-specific color palettes. Combine custom fonts and colors for a complete brand identity system.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro