Skip to main content
Tailwind CSS Mastery·Lesson 3 of 5

Custom Themes

Tailwind ships with a carefully designed default theme, but real projects need custom branding. Tailwind makes it straightforward to extend or override every design token.

Tailwind CSS 4: Theme Configuration

In Tailwind CSS 4, theme customization is done directly in your CSS using the @theme directive instead of a JavaScript config file:

Ctrl+Enter
HTML
CSS
JS
Preview

These tokens immediately generate utilities like bg-brand, text-brand-light, font-sans, rounded-card, and w-128.

Custom Color Palette

Define a full color scale for your brand:

Ctrl+Enter
HTML
CSS
JS
Preview

Now use these like any built-in color:

Ctrl+Enter
HTML
CSS
JS
Preview

Custom Fonts

Register font families in @theme and load them with @font-face or a service like Google Fonts:

@theme {
  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Cal Sans", "Inter", sans-serif;
}
<h1 class="font-display text-4xl font-bold">Welcome Back</h1>
<p class="font-sans text-gray-600">Here is your dashboard overview.</p>

Dark Mode

Tailwind supports dark mode via a CSS variant. In Tailwind CSS 4, configure it with @custom-variant:

@custom-variant dark (&:where(.dark, .dark *));

This makes the dark: variant apply when the dark class is on an ancestor element (typically <html>).

Toggling the Dark Class

function ThemeToggle() {
  const toggle = () => {
    const isDark = document.documentElement.classList.toggle("dark");
    localStorage.setItem("theme", isDark ? "dark" : "light");
  };

  return (
    <button onClick={toggle} class="p-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
      <span class="dark:hidden">Moon Icon</span>
      <span class="hidden dark:inline">Sun Icon</span>
    </button>
  );
}

Preventing Flash of Wrong Theme

Add a blocking script in <head> that reads the stored preference before the page renders:

Ctrl+Enter
HTML
CSS
JS
Preview

Styling for Dark Mode

Apply dark: variants alongside your default styles:

Ctrl+Enter
HTML
CSS
JS
Preview

CSS Variables for Dynamic Theming

CSS variables let you change themes at runtime without recompiling CSS. Define variables and reference them in @theme:

Ctrl+Enter
HTML
CSS
JS
Preview
<div class="bg-ui-bg text-ui-text">
  <a href="#" class="text-ui-accent hover:underline">Learn more</a>
</div>

This technique also works for multi-brand theming — swap variables based on a class or data attribute:

Ctrl+Enter
HTML
CSS
JS
Preview