Tailwind CSS is a core part of the Mostly Serious front end stack. Out of the box, it includes most of the utility classes you need to conditionally apply styles based on an element’s state.
Not only pseudo-classes, but aria states and more are available for you to write classes like the following:
However, there are occasions when you will want to style an element with a variant that doesn't exist out of the box, such as a custom loading state. In those cases, it’s helpful to create your own custom state variants, and Tailwind’s plugin system makes it easy to do with just a few lines of code.
Creating a custom Tailwind CSS state variant
In this example, we’re going to create an is-active: custom variant that lets us apply styles conditionally for any elements that have an is-active class.
In its simplest form, it looks like this:
This code can be added to your Tailwind config file as follows:
We are using Tailwind’s addVariant helper function to apply styles if an element has an is-active class. In a template, you'd use it as follows.
That's all it takes to create a new variant; and, if you are using the Tailwind CSS IntelliSense extension in VS Code, your custom state variants will auto-complete for you as well.
Abstracting this into a variant generator function
Now, what if you needed to make several custom variants? Of course, you could repeat the addVariant code, but you could also create a function to generate it for you and keep our code DRY.
Have a look at the next example config file in which we define a function named "is" to create custom state variants.
This function receives a name argument and returns an addVariant plugin configured for our variant. Now we can use in later in the config file as follows:
You can then use this function to create any is-* variants you need.
Creating custom utilities for global application state
Just as we have done for single elements, we can use this same pattern to create custom state utilities that target the document element or body to conditionally style child elements based on available features or the global application state.
For example:
- Style elements whether the method of input is keyboard or mouse. (You could use focus-within for this, too)
- Show or hide elements based on whether animations are enabled globally
- Test if the browser has access to Navigator.share
- Or indicate that the site’s global flyout menu is open
Theses scenarios and more are a great use for custom variants.
Will this work with future versions of Tailwind?
At the time of writing, plugins configured in javascript are on the roadmap to be supported in Tailwind 4 which is currently in development.
And recently there was a post on X showing a non-javascript way to configure variants in CSS.
Give custom variants a try
To sum up, Tailwind CSS plugins can be configured in just a few lines of javascript, and they make it easy to apply conditional styling for custom state. If there is not a built in utility class that meets your need, reach for addVariant and away you go.