csstailwind-cssvitepostcsstailwind-css-4

Custom @font-face Font Ignored by Tailwind CSS v4 with Vite and React


I'm trying to use a custom font (RetroGaming.ttf) in my React project using Vite and Tailwind CSS v4, but the font isn't applying. The @font-face rule seems ignored, and the generated Tailwind class doesn't include the custom font in its font-family property.

Tech Stack

Goal

Define RetroGamingFont via @font-face and apply it using a Tailwind utility class font-custom-retro.

Problem

  1. The custom font doesn't render; elements use the fallback font.
  2. The production CSS bundle (dist/assets/) lacks the @font-face rule.
  3. The generated .font-custom-retro class only includes the fallback font (sans-serif), not RetroGamingFont.
  4. Browser dev tools show no 404 error for [/fonts/RetroGaming.ttf]
  5. The issue persists whether @font-face is in src/index.css or directly in index.html.

Configuration

tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      fontFamily: {
        'custom-retro': ['RetroGamingFont', 'sans-serif'], // Font definition with fallback
      },
    },
  },
  plugins: [],
}

postcss.config.js

export default {
  plugins: {
    '@tailwindcss/postcss': {}, // Required for v4
    autoprefixer: {},
  },
}

src/index.css (Currently empty regarding @font-face)

@import "tailwindcss"; /* Tailwind v4 import, placed first */
    
/* @font-face moved to index.html for testing */

index.html (Current state)

<!-- Inside <head> -->
<style>
  @font-face {
    font-family: 'RetroGamingFont';
    src: url('/fonts/RetroGaming.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
  }
</style>

Usage in CompatibilityForm.jsx

<h2 className="text-2xl font-custom-retro text-pink-400">...</h2>
<label className="font-custom-retro text-indigo-200">...</label>

What I've Tried

Correct Tailwind v4 Setup:

@font-face Placement:

Neither worked.

File Path Verification:

Font Name:

Dev Tools Inspection:

Question

Why isn't Tailwind CSS v4 / PostCSS / Vite correctly processing or recognizing the @font-face rule, preventing the custom font from being included in the font-family definition of the utility class? Is there a specific configuration step for custom fonts with Tailwind v4 and Vite that I'm missing?


Solution

  • CSS-first configuration (recommended)

    Starting with TailwindCSS v4, the use of tailwind.config.js has been discontinued. Instead, a CSS-first configuration approach has been introduced. In the CSS-first configuration, you can customize your settings using the @theme directive. Various namespaces are available for this purpose.

    Note: In this case, the tailwind.config.js file can be deleted.

    With the --font-* namespace, you can declare fonts.

    /* Still, I'll show an example using a font that's available online. */
    @import url('https://fonts.cdnfonts.com/css/playground');
    
    /* Note: The font won't work here due to the absence of an online TTF file. */
    @font-face {
      font-family: 'RetroGamingFont';
      src: url('/fonts/RetroGaming.ttf') format('truetype');
      font-weight: normal;
      font-style: normal;
    }
    <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
    <style type="text/tailwindcss">
    @import 'tailwindcss';
    
    @theme {
      --font-retro: 'RetroGamingFont', sans-serif;
      --font-playground: 'Playground', monospace;
      --color-clifford: #da373d;
    }
    </style>
    
    <h1 class="font-retro text-clifford text-3xl font-bold underline">
      Hello world with Retro!
    </h1>
    
    <h1 class="font-playground text-clifford text-3xl font-bold underline">
      Hello world with Playground!
    </h1>

    Legacy JavaScript-based configuration

    As an alternative, you can still use tailwind.config.js via the @config directive.

    ./src/index.css

    @import 'tailwindcss';
    
    @config './../tailwind.config.js';
    
    @font-face {
      font-family: 'RetroGamingFont';
      src: url('/fonts/RetroGaming.ttf') format('truetype');
      font-weight: normal;
      font-style: normal;
    }
    

    tailwind.config.js

    /** @type {import('tailwindcss').Config} */
    export default {
      theme: {
        extend: {
          fontFamily: {
            'retro': ['RetroGamingFont', 'sans-serif'],
          },
        },
      },
      plugins: [],
    }
    

    Note: In this case, there's no need to declare content property. TailwindCSS v4 comes with automatic source detection.