I am using Tailwind CSS v4 and want to define custom colors that automatically switch between light and dark modes. Instead of using the dark:
prefix for every class, I want to manage color changes through CSS variables in my React project.
Here’s what I’m trying to achieve:
- Define custom colors (e.g.,
primary
,baseColor
,textColor
). - Automatically switch these values based on light or dark mode.
- Avoid using
dark:
in every class for better maintainability.
I’ve tried adding CSS variables via :root
and the dark
class but want to ensure I’m following best practices for Tailwind v4.
How can I configure tailwind.config.ts and global CSS to achieve this?
I am using Tailwind CSS v4 and want to define custom colors that automatically switch between light and dark modes. Instead of using the dark:
prefix for every class, I want to manage color changes through CSS variables in my React project.
Here’s what I’m trying to achieve:
- Define custom colors (e.g.,
primary
,baseColor
,textColor
). - Automatically switch these values based on light or dark mode.
- Avoid using
dark:
in every class for better maintainability.
I’ve tried adding CSS variables via :root
and the dark
class but want to ensure I’m following best practices for Tailwind v4.
How can I configure tailwind.config.ts and global CSS to achieve this?
Share Improve this question edited Mar 28 at 7:18 rozsazoltan 10.8k6 gold badges19 silver badges53 bronze badges asked Mar 28 at 6:01 Mourya PranayMourya Pranay 233 bronze badges 2- 1 Possible duplicated: How to use custom color themes in TailwindCSS v4 - Related: TailwindCSS v4 dark theme by class not working without dark tag – rozsazoltan Commented Mar 28 at 7:04
- How to manually toggle dark mode in TailwindCSS v4 – rozsazoltan Commented Mar 28 at 7:06
2 Answers
Reset to default 1TailwindCSS v4
From TailwindCSS v4 onwards, you can customize color appearance for any dark:
variant using @variant dark
. See bg-pink
in my example.
- Toggling dark mode manually - TailwindCSS v4 Docs
- How to manually toggle dark mode in TailwindCSS v4 - StackOverflow
- How to use custom color themes in TailwindCSS v4 - StackOverflow
- TailwindCSS v4 dark theme by class not working without dark tag - StackOverflow
@custom-variant
directive - TailwindCSS v4 Docs@variant
directive - TailwindCSS v4 Docs- Adding custom variants- TailwindCSS v4 Docs
@theme
directive - TailwindCSS v4 Docs - CSS-first configuration
document.querySelector('button').addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
});
<script src="https://unpkg/@tailwindcss/browser"></script>
<style type="text/tailwindcss">
/* changed the behavior of dark: (default: based on prefers-color-scheme) to work based on the presence of the .dark parent class */
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--color-pink: #eb6bd8;
}
@layer base {
@variant dark {
--color-pink: #8e0d7a;
}
}
</style>
<button class="size-20 bg-pink dark:text-white">Click Here</button>
<div class="w-50 h-12 bg-purple-200 dark:bg-purple-900 dark:text-white">
Lorem Ipsum
</div>
TailwindCSS v3
Before v4, in v3, this was only possible if you explicitly knew how to declare dark:
, which was typically done with .dark { ... }
. See bg-pink
in my example.
- Toggling dark mode manually - TailwindCSS v3 Docs
- Extending the default theme - TailwindCSS v3 Docs
tailwind.config = {
darkMode: 'class', // from v3.4.1 can use 'selector' instead of this
theme: {
extend: {
colors: {
pink: 'var(--color-pink)',
},
},
},
};
document.querySelector('button').addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
});
<script src="https://cdn.tailwindcss"></script>
<style type="text/tailwindcss">
:root {
--color-pink: #eb6bd8;
}
.dark:root {
--color-pink: #8e0d7a;
}
</style>
<button class="size-20 bg-pink dark:text-white">Click Here</button>
<div class="w-50 h-12 bg-purple-200 dark:bg-purple-900 dark:text-white">
Lorem Ipsum
</div>
You can try this approach to implement such in Tailwind v4:
Firstly, define CSS variables for theming.
/* globals.css */
/* Light Mode (Default) */
:root {
--color-primary: #3b82f6; /* Blue-500 */
--color-base: #ffffff; /* White */
--color-text: #1f2937; /* Gray-800 */
}
/* Dark Mode */
.dark {
--color-primary: #1e40af; /* Blue-900 */
--color-base: #1f2937; /* Gray-800 */
--color-text: #f3f4f6; /* Gray-100 */
}
- In your tailwind.config.ts file, you can configure it to use those CSS variables you have defined:
// tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
darkMode: "class", // Enables manual dark mode toggling
theme: {
extend: {
colors: {
primary: "var(--color-primary)",
base: "var(--color-base)",
text: "var(--color-text)",
},
},
},
plugins: [],
};
export default config;
Now you can use it in your React components as such:
<div className="bg-base text-text p-6 rounded-lg">
<h1 className="text-primary text-2xl font-bold">Stack overflow</h1>
<p>I love learning</p>
</div>
The classes bg-base, text-text, and text-primary will automatically adjust based on the active theme.
You can use localStorage to track the current theme or a state management library like Redux or Zustand. Choose the one that suits your needs best. I hope this helps solve your issue.