10/04/2021
Quick Tip TailwindCSS theming
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:
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.