- Published on
You’ve probably heard that a very alpha version of Tailwind CSS v4 has been open sourced.
It’s not ready for production yet, but let’s tale a look at how it simplifies setting up a multi-theme strategy.
Theme configuration in CSS
One of the key new features in v4 is the ability to customize the theme directly in a CSS file instead of the Tailwind config.
Theme values (like colors, font sizes, spacing) can be defined with CSS variables like so:
/* app/styles.css */
@import 'tailwindcss' @theme {
--color-primary: #aab9ff;
}
This is the equivalent of doing the following in Tailwind CSS v3:
// tailwind.config.ts
export default {
theme: {
colors: {
primary: '#aab9ff',
},
},
}
In v4, the CSS variables are also exposed in your CSS output, which means you can “consume” those variables anywhere you need it:
<div class="bg-(--color-primary)"></div>
Multi-Theme Strategy in Tailwind
If you’ve taken my Multi-Theme Strategy workshop, you know that the procedure to define themable CSS variables was somewhat convoluted:
1. Define CSS variables holding R
G
B
channels
:root {
--primary: 170 185 255;
}
2. Compose that CSS variable with an rgb()
function + <alpha-value>
to add a color in the tailwind.config.ts
file
theme: {
extend: {
colors: {
primary: rbg(var(--primary) / <alpha-value>)
}
}
}
Honestly, this is quite painful. And forces you to define your colors in a weird, custom format (space-separated R
G
and B
channels).
It’s way easier in Tailwind v4
Tailwind CSS v4 drastically simplifies the process of defining themable CSS variables:
1. Define a CSS variable with any color format, in CSS
@theme {
--color-primary: #aab9ff;
}
2. That’s it! there is no step 2.
You can redefine this variable value at different theme scopes like so:
@theme {
--color-primary: #aab9ff;
}
@layer base {
[data-theme='ocean'] {
--color-primary: #aab9ff;
}
[data-theme='rainforest'] {
--color-primary: #56d0a0;
}
[data-theme='candy'] {
--color-primary: #f9a8d4;
}
}
And that’s all you need to apply themable classes to your HTML:
Wait, why can’t I just use the
bg-primary
class?
Well, using the bg-primary
class directly would retrieve the actual HEX color defined in the @theme
block:
If you want to use “normal” utility classes like bg-primary
directly, you can go an extra step:
Mapping the @theme
CSS variables to another variable
You can define another CSS variable which will be consumed by the @theme
theme variable:
This time, the bg-primary
class will consume a CSS variable that changes for every theme scope.
No <alpha-value>
needed!
Did you notice we didn’t have to construct an rgb()
color composed with the <alpha-value>
?
Opacity support straight up works with HEX or any other color format, because Tailwind CSS v4 is using color-mix()
to compose the opacity:
Updating the Multi-Theme Strategy workshop
This all means that some parts of the Multi-Theme Strategy workshop could be simplified.
I say could, because right now, there is no Plugin API support for Tailwind CSS v4. There isn’t even support for the tailwind.config
file.
In other words, you can manually define themable CSS variables, but you can’t automate the process of passing a JSON theme to a plugin and have it generate all the theming parts for you.
When that becomes available, I’ll definitely look into upgrading the strategy to the best possible approach in v4!
Have a great day ❤️
I've teamed up with Kent C. Dodds to teach Tailwind CSS (and more) as a partner instructor on the Epic Web platform!
Pro Tailwind is an advanced-level course on Tailwind CSS, like multi-theme and multi-style component strategies. Sign up today!