One Simple Trick to Cleaning Up Tailwind CSS Code (v3)
Learn how to clean up repetitive Tailwind CSS classes in your markup by using the child selector variant to delegate styles to parent elements.
This is outdated since Tailwind CSS 3.4
Tailwind CSS can make your markup messy. However, we can prevent this by delegating classes to the parent element.
Let’s take the following example.
<ul>
<li class="text-sm font-medium text-gray-900">...</li>
<li class="text-sm font-medium text-gray-900">...</li>
<li class="bg-gray-100 text-sm font-medium text-gray-900">...</li>
</ul>
We have three repeating classes on the <li> elements.
text-smfont-mediumtext-gray-900
We can clean this up by moving these classes to the parent <ul> element and
letting the CSS cascade down.
<ul class="text-sm font-medium text-gray-900">
<li>...</li>
<li>...</li>
<li class="bg-gray-100">...</li>
</ul>
But what if we are using classes that cannot be delegated to the parent? Classes
like whitespace-nowrap, px-8, rotate-3 and many more cannot be applied to
child elements through cascading. Thankfully, there’s a solution…
Enter Tailwind CSS JIT
If you’re uncertain about JIT, you can refer to my blog What is JIT in Tailwind CSS? for a detailed explanation.
But here’s a short description.
Since v3, JIT has been the default in Tailwind CSS and has brought a lot of power to the framework. One of the best additions is arbitrary values, these allow you to replace custom CSS with Tailwind CSS-like classes.
Let’s use this example.
<ul>
<li class="p-4 text-sm font-medium whitespace-nowrap">...</li>
<li class="p-4 text-sm font-medium whitespace-nowrap">...</li>
<li class="bg-gray-100 p-4 text-sm font-medium whitespace-nowrap">...</li>
</ul>
Here we have four repeating classes.
whitespace-nowrapp-4text-smfont-medium
However, only two can be delegated to the parent.
text-smfont-medium
Here’s how it would look without JIT.
<ul class="text-sm font-medium">
<li class="p-4 whitespace-nowrap">...</li>
<li class="p-4 whitespace-nowrap">...</li>
<li class="bg-gray-100 p-4 whitespace-nowrap">...</li>
</ul>
We still have p-4 and whitespace-nowrap repeated on all the <li> elements.
Delegating Classes with JIT
Here’s how the example looks with JIT.
<ul class="text-sm font-medium *:p-4 *:whitespace-nowrap">
<li>...</li>
<li>...</li>
<li class="bg-gray-100">...</li>
</ul>
It’s the same as writing this.
& li {
//
}
Which translates to.
Select all first level children within this element
In our example, the & is the <ul> and the * is the <li> elements.
Here’s how it would look in CSS.
ul > li {
//
}
And from that, all we’re doing is applying CSS but with Tailwind CSS utilities.
ul {
@apply text-sm font-medium;
}
ul > li {
@apply p-4 whitespace-nowrap;
}
Here’s a more built-out example using a table component from HyperUI.
I’m unsure about this approach, as arbitrary classes have some downsides.
- Confusing to read
- Confusing to write
- Messy markup