light-dark() CSS function
With light-dark(), a color can be tied to the color-scheme. Based on the color-scheme, the browser selects the color corresponding to the current scheme. This essentially simplifies the declaration of light and dark themes, allowing it to be done in a single place, within @theme.
@theme {
--color-pink: light-dark(#eb6bd8, #8e0d7a);
--color-tsunami: light-dark(#77b4ea, #0d84ec);
}
Attention: TailwindCSS is shipped under the hood with LightningCSS. While LightningCSS does provide a fallback for older browsers to replace light-dark(), TailwindCSS does not apply it due to an open issue, meaning it is not available. TailwindCSS officially guarantees support starting from Baseline 2023, but light-dark() is a CSS function that was only stably introduced in Baseline 2024. This means that if you use it, your minimum browser version requirements will rise to the level where light-dark() was introduced. More details:
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 *));
/* WARNING: This way, instead of Chrome 111, at least Chrome 123 will be required, and instead of Safari 16.4, Safari 17.5 will be needed for it to work. */
@theme {
--color-pink: light-dark(#eb6bd8, #8e0d7a);
--color-tsunami: light-dark(#77b4ea, #0d84ec);
}
* {
color-scheme: light; /* apply "light" (first) color from light-dark() */
@variant dark {
color-scheme: dark; /* apply "dark" (second) color from light-dark() */
}
}
</style>
<button class="size-20 bg-pink dark:text-white">Click Here</button>
<div class="w-50 h-12 bg-tsunami dark:text-white">
Lorem Ipsum
</div>
var(--tw-light, ...) var(--tw-dark, ...) alternative
The previously mentioned question has an answer that explains how the behavior of light-dark() can be replicated with a little extra work. This way, you can avoid raising the minimum browser version requirement in your project.
@theme inline {
--color-pink: var(--tw-light, #eb6bd8) var(--tw-dark, #8e0d7a);
--color-tsunami: var(--tw-light, #77b4ea) var(--tw-dark, #0d84ec);
}
Note: Since @theme ships the given value into a global variable, the value cannot be a variable itself; otherwise, CSS cannot properly track the fallback values. Therefore, you should always use @theme inline. @theme inline does not embed the values into a global variable. However, it isn't necessary, since later on we don't want to override the color for other themes, as each theme can be declared locally in a single line.
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 *));
/* NOTE: It still works starting from Chrome 111 and Safari 16.4. */
@theme inline {
--color-pink: var(--tw-light, #eb6bd8) var(--tw-dark, #8e0d7a);
--color-tsunami: var(--tw-light, #77b4ea) var(--tw-dark, #0d84ec);
}
* {
color-scheme: light;
--tw-light: initial;
--tw-dark: ;
@variant dark {
color-scheme: dark;
--tw-light: ;
--tw-dark: initial;
}
}
</style>
<button class="size-20 bg-pink dark:text-white">Click Here</button>
<div class="w-50 h-12 bg-tsunami dark:text-white">
Lorem Ipsum
</div>