How to create multiple themes using Tailwind CSS?

Viewed 5392

Looking at Tailwind CSS, it seems that you need to specify specific colors in your classes like this:

<div class="bg-yellow-200 dark:bg-gray-800"></div>

But what if I want to offer 10 different themes that users can choose from in my web app? Like I might have themes like halloween and summer and winter and party etc.

I know that with regular CSS this is very easy done like this:

[data-theme="halloween"] {
    --color-bg: #000;
    --color-body: #757981;
}

<body data-theme="halloween"></div>

And then using Javascript I can change the data-theme property and the theme will change.

But how could I do this with Tailwind CSS? I couldn't find anything in the documentation about this.

3 Answers

I did actually found a solution using CSS variables.

In your css file you can define your styles for each theme like this

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
    [data-theme="default"] {
        --color-esther: 34, 39, 46;
        --color-maximus: 45, 51, 59;
        --color-linx: 55, 62, 71;
    }

    [data-theme="neon"] {
        --color-esther: 20, 61, 42;
        --color-maximus: 13, 82, 66;
        --color-linx: 20, 82, 11;
    }
}

Then in your tailwind.config.js file you can define them like this

function withOpacity(cssVariable) {
  return ({ opacityValue }) => {
    return opacityValue ? `rgba(var(${cssVariable}), ${opacityValue})` : `rgb(var(${cssVariable}))`
  }
}

module.exports = {
    //...

    theme: {
        colors: {
            'esther':       withOpacity('--color-esther'),
            'maximus':      withOpacity('--color-maximus'),
            'linx':         withOpacity('--color-linx'),
        },
    },
}

And in your html you can use these classes like this:

<html lang="en" data-theme="default">
    <body class="bg-esther text-optimus cursor-default">

    </body>
</html>

There are a couple of plugins that support defining multiple Tailwind themes, and switching between them. I particularly like the thailwindcss-themer plugin because it allows you to:

  • switch themes by simply adding a css class with the name of the theme on any component (usually the top-level component)
  • use CSS classes like you would normally do (e.g. text-primary). This keeps code clean and independent of the plugin (contrary to other plugins, which sometimes require a specific prefix on every CSS class)
  • use variants to further finetune styling, e.g. my-theme:font-bold

Just stumpled upon this question as I am doing the same what I already did a few years ago but couldn't remember anymore. In case anybody comes here again, maybe this answer might be helpful.

In our case, we are building a theme that is applied to 3 different websites but obviously changes colors and fonts, which seems to be the same case the question author has.

For this, tailwind presets can be used. I have one tailwind.preset.js which is basically the default tailwind configuration with all the base colors, spacings etc. For each theme, a separate tailwind.<theme-name>.js is set up that contains the changes and bases itself on the preset.

Example tailwind.theme-one.js:

module.exports = {
  presets: [
    require('./tailwind.preset.js')
  ],
  theme: {
    colors: {
      # color changes go here
    }
  }
}

We have a gulp workflow set up that basically just renders the main scss file once for each theme configuration. On the integrations, the required theme file is being loaded then.

Related