Episode 6 of 19

Custom Fonts

Add custom fonts to your Tailwind CSS project using Google Fonts, local @font-face declarations, and the Tailwind config. Make your designs stand out with custom typography.

Why Custom Fonts?

Default browser fonts are functional but generic. Custom fonts let you express brand personality and create visual hierarchy. In this tutorial, we will integrate Google Fonts into our Tailwind project and register them as custom utilities.

Method 1 — Google Fonts via CDN

The fastest way to add custom fonts is by linking them in your HTML <head>.

Step 1 — Import the Font

Head to Google Fonts, pick your fonts, and grab the link tag. For this tutorial, we will use Inter for body text and Poppins for headings.

<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=Poppins:wght@600;700;800&display=swap" rel="stylesheet">
  <link href="./dist/output.css" rel="stylesheet">
</head>

Step 2 — Register in Tailwind Config

// tailwind.config.js
module.exports = {
  content: ["./*.html"],
  theme: {
    extend: {
      fontFamily: {
        heading: ['Poppins', 'sans-serif'],
        body: ['Inter', 'sans-serif'],
      },
    },
  },
  plugins: [],
};

Step 3 — Use in HTML

<body class="font-body">
  <h1 class="font-heading text-4xl font-bold">Beautiful Typography</h1>
  <p class="text-lg text-gray-600">
    This paragraph uses Inter, while the heading uses Poppins.
  </p>
</body>

Set font-body on the <body> tag so all text inherits Inter by default. Use font-heading on headings where you want Poppins.

Method 2 — @font-face in CSS

For self-hosted fonts (better performance and privacy), download the font files and declare them via @font-face in your input CSS.

Step 1 — Download Font Files

Place your .woff2 files in a fonts/ directory:

project/
├── fonts/
│   ├── Inter-Regular.woff2
│   ├── Inter-Medium.woff2
│   ├── Inter-Bold.woff2
│   ├── Poppins-SemiBold.woff2
│   └── Poppins-Bold.woff2
├── src/
│   └── input.css
└── tailwind.config.js

Step 2 — Declare @font-face

In your src/input.css, add the font-face declarations before the Tailwind directives:

@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Poppins';
  src: url('../fonts/Poppins-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Poppins';
  src: url('../fonts/Poppins-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@tailwind base;
@tailwind components;
@tailwind utilities;

The font-display: swap ensures text remains visible while the font loads.

Step 3 — Register in Config

The Tailwind config remains the same as Method 1. The font family names must match the names used in @font-face.

Setting a Default Font

To make a custom font the default for all text, override the sans family in your config:

const defaultTheme = require('tailwindcss/defaultTheme');

module.exports = {
  content: ["./*.html"],
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter', ...defaultTheme.fontFamily.sans],
        heading: ['Poppins', 'sans-serif'],
      },
    },
  },
};

Now font-sans (the default font stack) uses Inter. Every element automatically inherits this without needing a specific class.

Google Fonts Performance Tips

  • Use preconnect — Add <link rel="preconnect"> tags for fonts.googleapis.com and fonts.gstatic.com.
  • Limit weights — Only load the weights you actually use. Each weight adds to the download size.
  • Use display=swap — Prevents invisible text during font loading.
  • Self-host for production — Download fonts and use @font-face for best performance and privacy.
  • Use woff2 — It is the most compressed font format with excellent browser support.

Practical Example — Blog Header

<header class="bg-gradient-to-r from-violet-600 to-indigo-600 text-white py-16">
  <div class="max-w-4xl mx-auto px-4">
    <p class="font-body text-sm uppercase tracking-widest text-violet-200 mb-2">
      Design & Development
    </p>
    <h1 class="font-heading text-5xl font-bold leading-tight mb-4">
      Mastering Custom Typography in Tailwind CSS
    </h1>
    <p class="font-body text-lg text-indigo-100 max-w-2xl">
      Learn how to integrate Google Fonts and self-hosted fonts
      into your Tailwind workflow for a unique brand experience.
    </p>
  </div>
</header>

Recap

  • Google Fonts can be loaded via CDN link tags or self-hosted with @font-face.
  • Register custom fonts in tailwind.config.js under theme.extend.fontFamily.
  • Override sans to set a new default font for the entire project.
  • Self-hosting with .woff2 files gives the best performance.

Next up, we will learn how to use Flexbox utilities in Tailwind.

Web DevelopmentTailwind CSSCSSTypographyFonts