I'm trying to set up a custom theme in Tailwind CSS v4 that auto-switches to dark mode without adding the dark:
prefix to every custom class.
In Tailwind v3, my setup was:
index.css:
:root {
--color-primary100: #0A7280;
--color-primary50: #BAD7DB;
--color-bgBase: #FDFDFD;
}
tailwind.config.js:
export default {
darkMode: 'class',
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
plugins: [tailwindCssForms, containerQueries],
theme: {
extend: {
colors: {
primary100: "var(--color-primary100, #0A7280)",
primary50: "var(--color-primary50, #BAD7DB)",
bgBase: "var(--color-bgBase, #FDFDFD)",
},
},
},
}
Toggling the dark mode by adding a dark
class to <html>
worked as expected without having to set a dark:bg-primary100-V2 bg-primary100
everywhere :
A single bg-primary100
will handle it both themes (multiply it by each customized props and you see why this is important)
After migrating to Tailwind CSS v4 (https://tailwindcss.com/docs/dark-mode), I updated my CSS using the new @theme
syntax :
@import 'tailwindcss';
@plugin '@tailwindcss/forms';
@plugin '@tailwindcss/container-queries';
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--color-bgContrast: #f9f9f9;
}
/*and was hopping for this to do the job but i tried many others */
@theme dark: {
--color-bgContrast: #66C8B6;
}
I expected that adding <html class="dark">
would update --color-bgContrast
to #66C8B6
, but it doesn't work as intended. My goal is to avoid duplicating styles with multiple dark:
prefixes across components everywhere.
Has anyone managed to achieve this centralized dark theme approach in v4 or faced a similar issue? Any insights or workarounds would be appreciated.
You seem to have used incorrect syntax. To set dark mode color variable values, you could do:
@layer theme {
.dark {
--color-bgContrast: #66C8B6;
}
}
theme
CSS cascade layer, where theme token related CSS rules go..dark
selector selects the HTML elements with the dark
class name.document.querySelector('button').addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
});
<script src="https://unpkg.com/@tailwindcss/browser@4.0.9"></script>
<style type="text/tailwindcss">
@import 'tailwindcss';
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--color-bgContrast: #f9f9f9;
}
@layer theme {
.dark {
--color-bgContrast: #66C8B6;
}
}
</style>
<button class="grid place-items-center size-20 bg-bgContrast">Toggle</button>