Extending Tailwind "modes" alongside dark mode

2.1k Views Asked by At

What is the best approach for adding your own themes for Tailwind in the same manner as dark mode?

The dark class is included within the HTML tag to signify that the page is now in dark mode, and we use the dark: selector when defining classes to style in that mode.

My question - how do we go about adding additional classes to the HTML tag and using additional custom selectors within styles to style in that particular variant?

I've read some plugin and variant documentation on the official Tailwind site, but it is not too clear what the right approach is here.

3

There are 3 best solutions below

1
On BEST ANSWER

The right approach is opinion based. You may use classes on html or body or any "global" selector, use custom data-attributes (like data-theme) etc

Here is example where I am using :has CSS selector to switch theme based on .theme element

It will not be available under some browsers as not all of theme has support for :has CSS selector

In order to use custom variant write simple plugin for it

const plugin = require('tailwindcss/plugin')

/** @type {import('tailwindcss').Config} */
module.exports = {
  plugins: [
    plugin(function({addVariant}) {
      // here is your CSS selector - could be anything
      // in this case it is `.theme` element
      // with `.theme--red` class (both present)
      addVariant('theme-red', '.theme.theme--red &')

      // and so on
      addVariant('theme-green', '.theme.theme--green &')
    })
  ],
}

Using Javascript toggle theme--red or theme--green classes on .theme element

<div class="theme">
  <div class="theme-red:bg-red-200 theme-green:bg-green-200 theme-red:text-red-700 theme-green:text-green-700">
    <h2 class="">Heading</h2>

    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Distinctio nam blanditiis vitae. Accusantium nostrum tenetur assumenda dolorum placeat, aliquam reprehenderit porro illum nam illo quis eum mollitia nulla atque delectus?</p>
  </div>
</div>
0
On

The easiest & cleanest solution is to use tw-colors

define your themes in tailwind.config.js

 const { createThemes } = require('tw-colors');

   module.exports = {
      content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
      plugins: [
         createThemes({
            light: { 
               'primary': 'steelblue',
               'secondary': 'darkblue',
               'base': '#F3F3F3',
            },
            dark: { 
               'primary': 'turquoise',
               'secondary': 'tomato',
               'base': '#4A4A4A',
            }
         })
      ],
   };

Then switch beetween themes as you like

<div class={someCondition ? 'theme-dark' : 'theme-light'}>
  ...
  <button class='bg-primary'>Click me</button>
  ...
</div>
0
On

I know I am late to the party here, but you can now just simply pass a selector, and the data tag, or class name in the tailwindcss config file now.

/** @type {import('tailwindcss').Config} */
module.exports = {
    darkMode: ['selector', '[data-mode="dark"]'],

    // ...
}

or you can have multiple selectors as well

/** @type {import('tailwindcss').Config} */
module.exports = {
    darkMode: ['variant', [
        '@media (prefers-color-scheme: dark) { &:not(.light *) }',
        '&:is(.dark *)',
    ]],
    // ...
}

This is useful for some plugins that manage dark mode in ways other than adding a class tag. I stumbled on this questions looking for the exact same thing actually.