As of TailwindCSS v2.0, Dark mode support is now provided out of the box!
It provides way more customization than the method noted below, and also, having it supported by the library itself will remove the need for you to keep repeating a manual method over and over for each of the projects you manage.
To learn more about the new support, please head to the new Dark Mode Documentation.
Dark mode 🌑 has been a hot topic in the UX land for quite some time, and it recently blew up with its official implementation in major Operating Systems during the last few months.
With this trend, many websites started to generate a Dark mode version of themselves, which may enabled manually by the user, automatically based on your device’s preference, or both ways.
Modern web browsers implemented this functionality recently with the
introduction of the
prefers-color-scheme
CSS Media Query.
We can use this feature to dynamically adjust the look of our websites to match
users preferred setting 😯.
In this post I’ll explain how to achieve automatic adjustment based on the
prefers-color-scheme
media query with TailwindCSS
⭐. If you would like to implement a manual-based switch, this is not for
you 😢.
TailwindCSS and its Utility-first Design
TailwindCSS allows the developer to use utility classes to define the look and feel of their websites, instead of needing to create complex CSS classes for your components ⚡. Also, it allows us to customize the configuration even further, by changing the default color palette, screen breakpoints, interactive variants, and way more! ✨
Implementing the prefers-color-scheme
Media Query
We don’t need to re-write all class utilities offered by Tailwind in order for them to switch between Dark/Light modes 😬, instead, we can use media queries to define our new color scheme the Tailwind way 🔥.
All we need to do is extend the responsive configuration in our
tailwind.config.js
file like this:
// tailwind.config.js
module.exports = {
theme: {
extend: {
screens: {
dark: {
raw: '(prefers-color-scheme: dark)',
},
},
},
},
}
This will add a dark
responsive utility that works like any size utilities
like sm
, md
, etc. This new responsive utility will come in handy when
defining (for example) which colors to use when a user’s color preference is set
to dark
.
A simple example will be to define a White background by default, and switch to a Darker one if possible. With our new responsive variant we could do something like this:
<!-- On your HTML code... -->
<body class="bg-white dark:bg-gray-900">
<!-- Your content here... -->
</body>
And that’s it folks, we can start implementing our own Dark website! 🎉
What about hover
or focus
?
This could be a tricky situation, for example, when you change the color of an
element based on a hover
interaction. The most common solution I’ve seen is
that many people end up implementing both a dark-hover
and dark-focus
variants.
The good news is that it’s not needed for most of the use cases 🧐.
There’s actually a (not so) secret Tailwind feature that allows us to combine responsive prefixes with interaction variants!
As seen in the Tailwind docs, we can use orange-based colors for a button on certain screen sizes, and green-based colors for the other screen sizes 😮:
<button
class="bg-orange-500 hover:bg-orange-600 sm:bg-green-500 sm:hover:bg-green-600 md:bg-red-500 md:hover:bg-red-600 lg:bg-indigo-500 lg:hover:bg-indigo-600 xl:bg-pink-500 xl:hover:bg-pink-600"
>
Button
</button>
Look carefully… There’s a sm:hover:bg-green-600
class! So, as our dark
query is a responsive prefix, then it means we could switch sm
for dark
and follow the same naming conventions to get hover
and focus
variants
working… And the answer is YES!
If we want to use a white
-based colors for a button in our Light scheme, and
gray
-based colors for the same button in our Dark scheme, we can write
something like:
<button class="bg-white hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700">
<!-- ... -->
</button>
This will indicate that:
- When on Light scheme, our button will have a white background, and a subtle gray when hovered.
- When on Dark scheme, our button will have a darker background, and a slightly lighter color when hovered.
With this, we can start expanding our coloring schemes to give those Dark users the feeling they truly want and prevent soaring eyes (DEV pun intended).