One Simple Trick to Cleaning Up Tailwind CSS Code (v3)
Published: / Updated:
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