Tailwind, Dark Mode and module.css

Light Dark Mode Example

Introduction

While setting up my web page and blog, I got stuck with an issue. I'm used to use file.module.css to apply CSS to the components (separation of concerns), and my surprise was that I wasn't able to use 'dark:' selector inside the module.css. Well, I was able to, but it didn't work.

Solution

The solution is very easy, and in my opinion, clean.

I found it in this link.

So, say you want to use dark mode in a single paragraph. Then you would use something like this, and it will work:

<p
  className="text-lg sm:text-2xl text-gray-800 dark:text-gray-200 text-center">
    Some text
  </p>

But, if you want to use that Tailwind CSS code for all the paragraphs, a good option is to use CSS modules to keep clean your component code, and set a class in there to configure styles to your paragraphs.

This is how I tried to do it in my first approach, and it does not work:

.p {
    @apply text-xl sm:text-2xl text-center;
    @apply text-gray-800 dark:text-gray-200;
  }

So, the solution is as simple as use ':global(.className)'. It is simple, but a bit tricky to understand. When using CSS modules we have the global selector to call global classes. As 'dark' is a global class, we call that class, and then, compose classes under that class. More or less.

.p {
    @apply text-xl sm:text-2xl text-center;
    @apply text-gray-800;
  }
  
  :global(.dark) .p {
    @apply text-gray-200
  }

And that is.

Thoughts

In the end, I find that this is good solution to the problem.

I like Tailwind and CSS modules, and with this, I have a nice looking solution, as I can divide my Tailwind declarations with @apply (one for text size and alignment, other for color, etc.), and then divide dark declaration for each class.

Demo project

I set up a public github project so you can test it and get a simple layout for any project you want with Next.js, Tailwind and Dark Mode enabled by default.

Check it, and thank you for reading!