Dark and Light Themes With Tailwind CSS and Nuxt.js
By: Maya Shavin
Tags: Programming, JavaScript, Front End Development, Nuxtjs, CSS

Toggle Dark/Light Mode With Tailwind CSS Classes

The tailwindcss-dark-mode plugin enables the variants for dark mode so that Tailwind CSS can generate the classes ready for use. To add the plugin to our app, run one of the following commands:

yarn add --dev tailwindcss-dark-mode #OR

npm i --save-dev tailwindcss-dark-mode

Then we set it for use in plugins as a Tailwind CSS plugin in tailwind.config.js .

/* ~/tailwind.config.js */ module.exports = {

//...

plugins: [require('tailwindcss-dark-mode')()]

}

This plugin injects all available dark mode variants to our app, such as

dark-hover (on hover), dark-group-hover (hovering on a group of elements)

(on hover), (hovering on a group of elements) dark-focus (when focusing on an element), dark-focus-within (when any of its child elements are focused on),

(when focusing on an element), (when any of its child elements are focused on), dark-active (when an element is in active mode)

However, it is not enough to start using it yet. We need to declare these variants with the core utilities we want to apply to them. Based on that, Tailwind CSS will map them and the related utilities to generated the new classes accordingly. To do so, we define the needed variants with the desired CSS utilities inside the variants field of tailwind.config.js , as shown below:

Tailwind CSS will generate the additional classes for dark mode according to the following syntax:

${dark-mode-variant}:${normal-generated-class-for-css-property}

Two examples are dark:bg-green-yellow to apply the green-yellow color variant to background-color and dark-hover:bg-green to apply the green color on the background when the element is on hover.

And lastly, we need to inform Tailwind CSS that our .dark-mode class selector is the main selector for dark mode by mapping it to the darkSelector field of theme in tailwind.config.js :

module.exports = {

theme: {

darkSelector: '.dark-mode',

}

}

Behind the scenes, Tailwind CSS will auto-generate the CSS rule set for dark mode according to the assigned selector, .dark-mode .

An example of setting border-color of a button to white color on dark mode is as below:

The generated CSS style on the client side will be something similar to:

.dark-mode .dark\:border-white {

border-color: #fff;

}

This approach ensures the explicit use of dark mode selectors over other Tailwind CSS selectors.

And that’s all it takes. We can now indicate the style for dark mode for any CSS utilities with the dark mode variants included in variants by following the class syntax mentioned above.

For example, suppose we want to make a simple card following the below design:

We first define the card template:

With the base styles, which are consistent in both modes:

Let’s add some required styling for light mode (as our default mode), such as:

border-white and bg-green-lime to the card wrapper div.card

and to the card wrapper bg-gray-300 to the image placeholder div.placeholder

to the image placeholder bg-blue-300 and hover:bg-blue-500 for hover state to the card's main button button.card-btn

And the corresponding classes for dark mode, starting with dark: :

dark:border-gray-700 and dark:bg-green to div.card

and to dark:bg-gray-600 to div.placeholder

to dark:bg-blue-700 and hover state dark-hover:bg-blue-300 to button.card-btn

The result is:

We can apply the same approach to style our entire app at the minimum effort needed for theming. Less code to write — isn’t that awesome?

Important note: The class dark-mode is assigned programmatically on runtime and does not appear manually as a class value for any component in our code. Hence PurgeCSS will remove all the generated stylings and classes related to it on bundling, as it understands wrongly that this is an unused CSS selector. To prevent this specific behavior, we need to add dark-mode to the list of whitelist selectors for purgeCSS we'd like PurgeCSS to include in nuxt.config.js .

/* ~/nuxt.config.js */ module.exports = {

purgeCSS: {

whitelist: ['dark-mode']

}

}

So far, so good?

Next, we are going to see how we can structure our theming configuration in a reusable and organized way.