Using SplitCSS to remove unused Tailwind CSS classes
Tags: showdev, tailwindcss, css
Published: 2020-04-21 19:53:16

Utility CSS frameworks are a great way to style your web application nowadays. However, popular CSS frameworks like TailwindCSS can generate a lot of classes that are not used on majority of your web pages.

Even after using some CLI tools, there will still be classes that most of your URLs don't need.

Think about it, even if your web application has styled HTML tables on one URL, a CLI tool will let those classes for styling HTML tables in the entire stylesheet, for every URL. Same goes with borders, lists etc.

If you define multiple colors in your TailwindCSS palette, there will be even more classes.

As a result, the browser has no choice but to download the entire stylesheet, even if it needed only a small portion of it.

You may think that unused CSS is not much of a big deal in the age of high-speed Internet connections, but in reality, most users use their mobile devices to surf the Internet.

And unless connected to a Wi-Fi network, they don't have such a fast connection.

Moreover, as engineers, we should always aim to optimize performance and never leave unnecessary stuff in the product.

Just because a product is functional, does not mean that its developers are excused for leaving unused stuff in it.

## Removing unused Tailwind CSS styles with SplitCSS API 

Let's download  [Tailwind](https://tailwindcss.com/)  and configure it.

Here is our `tailwind.config.js` file:


```
module.exports = {
    theme: {
        colors: {
            white: '#fff',
            black: '#000',
            green: '#3FBD0C',
            gray: {
                light: '#dadada',
                dark: '#2D3449',
                darkest: '#222838'
            }
        },
        extend: {},
    },
    variants: {},
    plugins: [],
}
``` 

Next, let's configure Webpack to output our Tailwind-powered stylesheet in a file called tw.css

So now, let's create an `index.php` page:

```
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>Index Page</title>
    <link rel="stylesheet" href="/tw.css">
</head>

<body>
    <h1 class="mt-8">index.php</h1>
    <p class="px-4 py-2">This is my index page.</p>
</body>

</html>
```

We have inserted our stylesheet in the `<head>` section.

As you can see, our page uses only a few of Tailwind's classes. It does not use the utility classes created for our color palette.

Most of what Tailwind came with is unused by our page, even if we had purged our files by scanning them.

---

Now, in order to remove the unused Tailwind CSS, let's pull in SplitCSS API.

In order to give the browser only the styles that are needed for the current URL, we will use the SplitCSS API.

First, let's go ahead and  [create a free SplitCSS account](https://splitcss.com/register)  and generate an API key.

Now, let's create our proxy script, `styles.php`:

```
<?php
$apiToken = 'MY_API_TOKEN'; // replace with your real one
$htmlUrl = $_GET['html_url'];
$cssUrls = $_GET['css_urls'];
$output = 'css';
$splitCssUrl = "https://api.splitcss.com/clean-css?html_url={$htmlUrl}&css_urls[]={$cssUrls}&output={$output}&token={$apiToken}";
echo file_get_contents( $splitCssUrl );
```

Now let's pass the `styles.php` along with the URLs we want to optimize for:

```
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>Index Page</title>
    <link rel="stylesheet" href="/styles.php?html_url=https://example.com/index.php&css_urls[]=https://example.com/tw.css">
</head>

<body>
    <h1 class="mt-8">index.php</h1>
    <p class="px-4 py-2">This is my index page.</p>
</body>

</html>
```

The CSS file that will be delivered to the browser, will look like this:

```
.mt-8 {
    margin-top: 2rem;
}

.px-4 {
    padding-left: 1rem;
    padding-right: 1rem;
}

.py-2 {
    padding-top: .5rem;
    padding-bottom: .5rem;
}

...
/* Plus all the responsive variants for these utilities */
```

But what is most interesting is that none of the color-utilities based on the tailwind.config.js will appear in the output, because they are not used in this HTML document.

This will drastically reduce the stylesheet filesize. The exact size will depend on how many Tailwind classes do you use in your HTML document.

Of course, in a real application you will want to pass the HTML URL dynamically so you will always get only the Tailwind classes that your browser needs.

## Removing unused CSS in Tailwind applications with conditionally loaded content

In real-world scenarios, applications often load some content conditionally.

For example, let's imagine we have a blog website. Some posts have comments, some don't.

Because we cannot predict when the next comment will come, we have the following choice:

1) always load the styles for the comments
2) invalidate the SplitCSS cache when the first comment comes.

In the first scenario, we can mark the comment styles so that SplitCSS ignores them:

```
/* uncss:ignore */
.tw-button {
@apply bg-green text-white px-4 py-2
}
```

Since SplitCSS is built on top of UnCSS, placing these comments before the actual classes will cause SplitCSS to include them in the resulting stylesheet.

This can be relatively easily done for your custom utilities. For all the pre-built utilities that Tailwind comes with, it can be quite tedious.

That's why it's better to take the second scenario.

We can invalidate the SplitCSS cache when the first comment has been submitted.

To achieve this, we can call the SplitCSS API upon submitting the first comment:

```
$commentData = $request->only(['email', 'title', 'body']);
$postId = $request->get('post_id');
$post = $postRepository->find( $postId );
if( $post->comments()->count() ) {
$apiKey = config('splitcss.api_key');
$postUrl = $post->url();
$apiUrl = "https://api.splitcss.com/invalidate?token={apiKey}&html_url={$postUrl}";
file_get_contents( $apiUrl );
}
$comment = $commentRepository->save($commentData);
$post->comments()->attach($comment);
```

The code above will [invalidate the SplitCSS cache](https://splitcss.com/documentation#invalidate-all) when the first comment is submitted.

By doing this, the user will see the comment styled properly.

## Conclusion - save bandwidth for every URL by removing unused CSS classes in Tailwind

We are big fans of TailwindCSS and we think it's a great way to write stylesheets for modern websites.

To speed up your website and improve the performance, you can use the SplitCSS API to serve the Tailwind classes that the browser needs in order to render the current URL.

This can be in combination with CLI tools that scan your source files for classes.

If you have further questions regarding using Tailwind in combination with SplitCSS, feel free to check out the [FAQ](https://splitcss.com/faq) section.