GitHub

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.

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.

However, only two can be delegated to the parent.

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.