Create Custom Themes in Tailwind CSS v4 – @custom-variant (1/2)


Themes define the visual style and layout of a website, making the user experience more enjoyable. In this article, I’ll show you how to create different themes using Tailwind CSS.

Note: I used AI tools to help draft and structure this article because I’m still building my technical writing skills. However, all the code was written, tested, and reviewed by me.

Featured Image




1. Add custom variants with @custom-variant

You can create new themes or conditional styles through custom variants added by the @custom-variant directive. But first, here are some important points to consider:

  • Define in index.css: Add @custom-variant declarations to your main CSS file (e.g., index.css).

  • Enable dark mode: Create a dark variant and activate it using the data-theme attribute.

  • Maintain consistent naming: Use a short name like dark for dark mode, and prefix other themes with theme-.




Method 1: Nesting syntax

This method allows nesting additional rules within the block:

@custom-variant dark {
    &:where([data-theme="dark"] *) {
        @slot;
    }
}

@custom-variant theme-midnight {
    &:where([data-theme="midnight"] *) {
        @slot;
    }
}
Enter fullscreen mode

Exit fullscreen mode

Example applying styles only on devices that support hover:

@custom-variant any-hover {
    @media (any-hover: hover) {
        &:hover {
            @slot;
        }
    }
}
Enter fullscreen mode

Exit fullscreen mode

Note: This rule only applies to devices that support hover (e.g., desktops or laptops), and not to touch-only devices like phones or tablets.




Method 2: Shortcut syntax

This syntax is useful when you don’t need to nest other rules:

@custom-variant dark (&:where([data-theme="dark"] *));
@custom-variant theme-midnight (&:where([data-theme="midnight"] *));
Enter fullscreen mode

Exit fullscreen mode




2. Apply theme-specific styles in markup

Once data-theme is set, you can apply conditional styles using your custom variant prefix in your utility classes:

 class="bg-white theme-dark:bg-black-800 theme-midnight:bg-purple-800">
Enter fullscreen mode

Exit fullscreen mode




3. Set themes via data-theme attribute

To activate a theme, set the data-theme attribute on the tag:

 data-theme="midnight" lang="en">
Enter fullscreen mode

Exit fullscreen mode

You can dynamically change the value to switch themes:

 data-theme="light" lang="en"> 
 data-theme="dark" lang="en">
 data-theme="midnight" lang="en">
Enter fullscreen mode

Exit fullscreen mode




4. Bonus: Component to switch between themes dynamically

This example uses a