I’m building a simple dark mode toggle using Tailwind CSS v4.1. The dark mode switching itself works fine, but the transition effect doesn’t apply — the colors switch instantly instead of fading smoothly.
document.addEventListener("DOMContentLoaded", () => {
const darkModeSwitch = document.getElementById("dark-mode-switch");
const html = document.documentElement;
// Load saved theme
const savedTheme = localStorage.getItem("theme");
if (savedTheme === "dark") {
html.setAttribute("data-theme", "dark");
darkModeSwitch.checked = true;
} else {
html.setAttribute("data-theme", "light");
darkModeSwitch.checked = false;
}
// Toggle theme
darkModeSwitch.addEventListener("change", () => {
if (darkModeSwitch.checked) {
html.setAttribute("data-theme", "dark");
localStorage.setItem("theme", "dark");
} else {
html.setAttribute("data-theme", "light");
localStorage.setItem("theme", "light");
}
});
});
<html lang="en" class="transition-colors duration-500 ease-linear">
<head>
<script src="https://unpkg.com/@tailwindcss/browser"></script>
</head>
<body class="bg-gray-500 dark:bg-gray-800">
<div class="flex h-[100vh] flex-col items-center justify-center gap-3">
<div class="flex flex-col items-center gap-3 text-2xl font-[300] text-black dark:text-white">
<label for="dark-mode-switch">Click To Switch</label>
<input type="checkbox" id="dark-mode-switch" class="size-10" />
</div>
<div class="size-96 bg-gray-400 dark:bg-blue-900"></div>
</div>
</body>
</html>
In my input.css, I added custom spacing like this:
@import "tailwindcss";
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
Tailwind Setup:
What I’ve Tried:
transition-colours duration-500 ease-linear
on <html>
tag.transition-colours
to <body>
and other elements.Question:
How can I enable a globally smooth background/text color transition when toggling dark mode in Tailwind CSS v4.1?
Do I need to adjust my dark: configuration, or is there a better way to apply transition colors globally for dark mode toggles?
I would simply add it to *
in CSS:
document.querySelector('button').addEventListener('click', () => {
document.documentElement.classList.toggle('dark');
});
<script src="https://unpkg.com/@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 theme {
* {
@apply transition-colors duration-500 ease-linear;
}
:root, :host {
@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>