10/04/2021

Quick Tip TailwindCSS theming

post banner

A consistent theme is an essential part of today’s applications. Most of the time theming is only reduced to have a nice fitting color scheme. However theming is more. It is the complete look of an application.

For the sake of simplicity I will focus in the examples also only in showing how to setup a theme in terms of defining a color-theme.

Prerequisites

  • Setup TailwindCSS for your application. The official documentation provides a lot of guides for different frameworks/tools.
  • Have a basic understanding how the tailwind.config.js works.
  • Know how CSS custom properties work.

Theming

Basically there are two ways to setup a theme:

  • Overriding/extending the default components individually
  • Defining a global extension which will extend every component

We will step over both having a look at a call to action button as example:

Grant types

As you can see in this simple example depending on the theme (light or dark), the button will change it’s look.

Extending default components

First we’ll need to define some custom CSS properties:

:root {
  --color-text-cta: black;
  --color-bg-cta: #FDE68A;
}

.dark {
  --color-text-cta: white;
  --color-bg-cta: #16A34A;
}

Next we need to extend our tailwind.config.js:

module.exports = {
  // ... 
  theme: {
    extend: {
      textColor: {
        cta: "var(--color-text-cta)",
      },
      backgroundColor: {
        cta: "var(--color-bg-cta)",
      },
    },
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

Note that we are in the extend-object of theme. So we are not overriding the default tailwind config but extending it.

We defined two new properties in textColor and backgroundColor. Both will be accessible via the defined name cta and they are referencing the custom properties defined in the previous step.

After doing so we’re able to style our button:

<button className="py-2 px-4 rounded-lg font-semibold border border-black bg-cta text-cta">
    Click me
</button>

There you can see by some TailwindCSS-magic the classnames bg-cta and text-cta are available. These names are also quite good readable as they can be clearly be related to a specific use-case

Global extension

The second possibility is to extend the colors-object which is provided by TailwindCSS. This will result in new variations for each component.

To do so we again need to define some CSS custom properties:

:root {
  --color-theme-primary: #FDE68A;
  --color-theme-secondary: black;
}

.dark {
  --color-theme-primary: #16A34A;
  --color-theme-secondary: white;
}

Next we need to extend our tailwind.config.js:

module.exports = {
  // ... 
  theme: {
    extend: {
        colors: {
        'theme-primary': 'var(--color-theme-primary)',
        'theme-secondary': 'var(--color-theme-secondary)',
      },
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

Note: we are now extending the colors-object.

After doing so we’re able to style our button like this:

<button className="py-2 px-4 rounded-lg font-semibold border border-black bg-theme-primary text-theme-secondary">
    Click me
</button>

Now we do have bg-theme-primary and text-theme-secondary available.

You might already see some downsides of this approach. The names are very generic and no longer self explaining like in the first example. Also in larger applications you might get into trouble to apply the theming. However the positive point about this approach is that you restrict your color-theme to a minimal amount of colors.

When to use which approach?

As always it depends. Usually I follow to extend the default components. It is a little more work as you need to extend every component which you want to use but it gives me more flexibility and I like to have readable use-case-specific class names.

Further info


post banner
Michael Berger

About the Author

I am a seasoned Fullstack Software Engineer with a focus on building high-performant web applications and making teams better.

If you are looking for support on building a scalable architecture that grows with your business-needs, revisit and and refine your testing-strategy as well as performance-optimizations, feel free to reach out to me.

I am always looking for new challenges and interesting projects to work on. Check out my website for more information.