Setting and using CSS variables in Tailwind with React
Why?
I often get the question to make a component themeable through a configuration in a CMS (or another datasource).
Usually when I hear theming, the first thing that comes to mind is CSS variables.
But I don’t want to be using a useEffect
with setProperty.
Implementation
The CSS variables are not set yet, so I add them to my global CSS.
Now I can use these colors in my component using arbitrary values.
This will have the following output:
Now let’s make the component themeable. I add a prop “variant” to the component, which will be used to set the CSS variables.
If the variant prop has the value “highlighted”, the component will change the variables for the CTA’s background color and text color using the [--VARIABLENAME:VALUE]
syntax.
Setting the CSS variable this way will only affect the component and not the whole page due to the scoping.
So when I now use the component with the variant “highlighted” <Cta variant="highlighted" />
, the background color and text color will change.
Now what if I would have dynamic rich text content coming from the CMS, which could contain HTML elements, and I want to apply theming to those elements too?
This approach can easily be extended to support that.
In Tailwind you can use the [&_ELEMENTNAME]
syntax to target an element inside a component.
Without variant
Code:
Output:
- List item 1
- List item 2
With prop variant="highlighted"
Code:
Output:
- List item 1
- List item 2
Notice how the link and list item bullets coming from the external HTML are now yellow.
Conclusion
I know it’s possible to use inline styling to set CSS variables too, but I don’t like the syntax for inline styling and this would not work for the dynamic content coming from an external source, since we don’t have control over the HTML structure. With this approach we can do everything using the power of Tailwind, which is what I prefer in all cases. The code for this can be found on my GitHub.