tailwind-csstailwind-css-4

How to enable globally smooth color transition for dark mode toggle in Tailwind CSS v4.1?


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:

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?


Solution

  • 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>