Custom Fonts and Colors in Tailwind CSS v4

Krishna AkbariKrishna Akbari
5 min read

I started working with Tailwind CSS v4 and immediately noticed how effortlessly it flows compared to v3. If you’ve been building with Tailwind especially in a Vue.js project you’ll likely spot some changes that take a moment to get used to.

Whether you’re refreshing an old site or starting something brand new, understanding how Tailwind v4 handles fonts and colors will save you a lot of time and frustration

Ready to start? Let’s go!

  • What’s new in Tailwind v4 compared to the old version

  • How to create our colors using the new @theme feature

  • Adding custom fonts, including Google Fonts

  • Real examples with Vue.js, and responsive fonts

Why Fonts and Colors Matter

Fonts and colors do more than just make your site look good they set the tone and help people remember who you are. In earlier versions of Tailwind, tweaking these required jumping back and forth between your CSS and a JavaScript config file, which quickly became a hassle.

Tailwind v4 made this a lot simpler. Now you define your fonts and colors right inside your CSS using a new rule called @theme. This means we don’t have to jump around our files anymore. I liked this a lot because everything I need is in one place.

What’s Changed in Tailwind v4?

Before (in version 3), you did something like this in your config:

module.exports = {
  theme: {
    extend: {
      colors: {
        brand: "#48A9FA", // custom blue for our brand
      },
      fontFamily: {
        heading: ["Space Grotesk", "sans-serif"], // font for headings
        body: ["Inter", "sans-serif"],            // font for body text
      },
    },
  },
};

But now in v4, we write this instead, inside our CSS:

@import "tailwindcss";

@theme {
    --color-primary: #181E2A;
    --font-heading: "Space Grotesk", "sans-serif";
}

At first, I thought it was strange not to have the JS config, but the CSS approach felt more natural after a while. It lets you see all your theme stuff in one place, and it works better for switching colors for dark mode or different themes.

How I Created My Colors

To set my colors, I put this block in my main CSS file:

@theme {
    --color-primary: #181E2A;
    --color-accent: #48A9FA;
    --color-gold: #FFCF69;
    --color-background: #F5F7FA;
    --color-muted: #8E91A7;
}

This makes utility classes like bg-primary, text-primary, and border-primary work automatically.

If you want different shades, just add more variables like:

--color-primary-100: #24324a;
--color-primary-200: #2d3b59;

I also added colors for success, errors, warnings, and info messages:

@theme {
    --color-success: #22c55e;
    --color-error: #ef4444;
    --color-warning: #f59e42;
    --color-info: #3b82f6;
}

And don’t worry, Tailwind’s default colors still work alongside our custom ones.

How I Add Fonts In Style

Here’s how I usually bring fonts into my Tailwind setup gives the site its own personality:

First, I declare my font variables in my CSS:

@theme {
    --font-heading: "Space Grotesk", "sans-serif";
    --font-body: "Inter", "sans-serif";
}

Then I load the Google fonts in my <head>:

<link
  href="https://fonts.googleapis.com/css2?
    family=Inter:wght@400;700&
    family=Space+Grotesk:wght@400;700&
    display=swap"
  rel="stylesheet"
/>

If you’d rather import directly from your CSS, you can do:

@import url(
  'https://fonts.googleapis.com/css2?
   family=Inter:wght@400;700&
   family=Space+Grotesk:wght@400;700&
   display=swap'
);

Want to use a custom font instead? Drop in an @font-face:

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

@theme {
    --font-heading: 'Lobster', cursive;
}

Then use the font classes like this:

<h1 class="font-heading text-4xl">
  Big, bold headline
</h1>
<p class="font-body text-base">
  A nice chunk of body text to read.
</p>

Quick tip: Only load the font weights you actually use — it helps your site load faster.

Some Real Examples I Use in Vue.js

This is how I use my custom fonts and colors in a Vue.js component:

<template>
    <div class="bg-brand text-white font-heading p-6 rounded-lg max-w-sm mx-auto shadow-lg">
        <h1 class="text-2xl font-bold text-primary mb-2">Welcome to My Portfolio</h1>
        <p class="font-body text-muted mb-4">
            Hi, I’m a frontend developer passionate about building clean and responsive websites using Vue.js and Tailwind CSS.
        </p>
        <button class="mt-4 bg-accent text-white px-5 py-2 rounded hover:bg-purple transition duration-300">
            Contact Me
        </button>
    </div>
</template>

Responsive Text? Easy!

Tailwind makes it super simple to adjust text size for different screen sizes. It just works out of the box. Here’s a real example from a small personal blog header and paragraph that adapt based on the device you’re using:

<h1 class="font-heading text-2xl md:text-3xl lg:text-5xl">
    My Journey with Tailwind CSS
</h1>
<p class="text-base md:text-lg">
    This blog shares tips and tricks I learned switching from Tailwind v3 to v4—responsive and easy going.
</p>

A Few Tips That Helped Me

  • Use clear prefixes like --color- and --font- so your theme variables make sense

  • Keep a simple list of your colors and fonts for yourself and your team

  • Use Tailwind’s purge tool to remove unused CSS and keep your files small

  • If you have several projects, share your theme CSS so it’s easier to reuse

  • Check color contrast for accessibility — it’s important!

  • Use browser dev tools to check if your fonts and colors apply

To Wrap Up

Switching to Tailwind v4 made styling way easier for me. It took a bit to get used to, but having fonts and colors set inside CSS files feels more natural. Plus, builds are faster, which is always nice. If you’re coming from v3, don’t try to change everything at once start with one component and go from there.

0
Subscribe to my newsletter

Read articles from Krishna Akbari directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Krishna Akbari
Krishna Akbari