The most underrated Tailwind feature
16 September 2023
By Bogdan-Mihai Gligor
Having the power to have a standardized way of writing atomic classes is surely Tailwind's greatest achievement. The way we can add media queries, dark theme behaviors, hover and focus and many other modifiers to our styles is the cherry on top. All Tailwind users know and use these features quite extensively. But there is one feature that is by far forgotten (or just unknown) by most of this style library's users.
I think that by far the most underrated Tailwind feature is arbitrary variants.
I'm sure some of you are not familiar at all with the concept of arbitrary variants.
And I don't blame you. I haven't heard of it either for the longest time. The first time
I encountered this feature was when I was searching for a good styling example for
a <details>
tag. It was used to animate and update an arrow <svg>
tag within a
<summary>
tag. Something similar to the code below:
<details className="[&_svg]:open:rotate-180"> <summary> <svg className="rotate-0 transform transition-all duration-300" /> <span>{title}</span> </summary> </details>
What do arbitrary variants actually do? And how do they work?
Arbitrary variants basically allow you to target specific tags within the parent tag. Here are some examples as to how this feature translates to vanilla CSS:
[&_div]:
& div { /* styles */ }
[&_.someclass]:
& .someclass { /* styles */ }
[&>.someclass]:
&>.someclass { /* styles */ }
[&_div_.someclass]:
& div .someclass { /* styles */ }
[&[open]_span]:
&[open] span { /* styles */ } /* this one could be rewritten as [&_span]:open: */
The &
is just the element within which you are writing the arbitrary variant
in. The rest is just CSS selectors, with _
for space. Once you understand
this, it gets much easier to write custom variants that target exactly what you
want.
That's what makes this feature so powerful. The ability to "programmatically" apply styles to elements within the one you are basing your modifiers on.
Caveats
After seeing the first example, you might start thinking: Couldn't something similar
be done with group
and group-hover
? I guess it could. But that's missing the
point. This feature allows for a much more atomic way of linking modifiers to styles
tha grouping ever could.
Let's look at the example below:
<details className="[&_.close]:open:inline [&_.modify]:open:hidden"> <summary> <span className="modify">Modify</span> <span className="close hidden">Close</span> </summary> </details>
I can conditionally control what text is being shown in the <summary>
tag,
by checking whether the <details>
tag is open or not. With pure CSS. No need for
useRef()
or other less than ideal approaches. This is currently being used on this
very website:
Why is this feature not as widely known?
My guess would be the hard to wrap around syntax it uses. It needs some getting used to, and even then, you need to understand CSS selectors to actually use it properly. Anyways. Here are some more resources on this topic:
Official Docs
Stack Overflow post on the topic
Where I found out about arbitrary variants
Check out my other blogs here.