Tailwind & PurgeCSS

Web Dev / 4th July, 2021

Before we start

This post assumes that you already have a web project up and running (I won’t go into the ins and outs of creating one here) and that you have the npm package manager installed, as well as the module bundler webpack.

If you neither npm or webpack installed, please first install node.js (which includes npm) from: https://nodejs.org/en/

Next run the following from the command line to create a package.json file:

npm init -y

Note: Within your package.json file to run webpack when the npm run build command is ran, you must add “build”: “webpack” to the “scripts” property. Like so:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
    "build": "webpack"
}

Finally, run the following command to install webpack:

npm install webpack webpack-cli --save-dev

What is Tailwind CSS?

Tailwind is a utility-first CSS framework, which reduces the need to write vast amounts of CSS, by giving you the ability to add a wide array of pre-defined classes directly to your mark-up. This makes the process of creating custom web pages quick and painless.

It is important to note that Tailwind is not opiniated and it is highly customisable, which makes extending the framework to fit your own bespoke needs incredibly easy. I will go through how to extend the framework later in this post.

What is PurgeCSS?

PurgeCSS is a tool used to remove unwanted CSS. It is particularly useful when using a CSS framework such as Tailwind, where you have a large set of utility classes (resulting in a large CSS file), but only use a fraction of those classes/CSS.

In short the tool analyses your content e.g. html, php, vue files and then determines which classes aren’t in use and removes (purges) the relevant CSS. This can significantly reduce the size of your CSS.

Using Tailwind without PurgeCSS would result in a CSS file size of 3.7mb! Therefore it is incredibly important that PurgeCSS is integrated into your development process.

Installing Tailwind & PurgeCSS (+ other packages)

Firstly we are going to install Tailwind CSS, PostCSS (as well as PostCSS loader) and Autoprefixer. Autoprefixer is a tool that is used to parse CSS and then add any appropriate vendor prefixes. This helps to ensure that your CSS is cross-compatible across a wide range of web browsers. PostCSS and PostCSS loader will be used to process CSS within our webpack config file.

To install all four packages, run the following two commands:

npm install tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9 --save-dev

npm install postcss-loader@~3.0.0 --save-dev

Next we will install “css-loader”, which will be used to resolve imports within our webpack entry file.

npm install css-loader --save-dev

Next we will install “cssnano”, which will be used to minimise our final CSS file (decreasing its file size).

npm install cssnano --save-dev

Next we will install “mini-css-extract-plugin”, which will be used to extract our CSS into a sperate file.

npm install mini-css-extract-plugin --save-dev

Finally, we can install PurgeCSS.

npm install purgecss-webpack-plugin --save-dev

Note: Running these commands will ensure that that the relevant packages are added to your node_modules folder. As well as this the dependency will be added to your package.json file

Setting things up

From here, if you don’t already have one,  you can go ahead and create a new CSS file e.g. /css/style.css.

Note: Our outputted CSS file will exist in a dist folder. At this stage you can link this file to your web page e.g. <link rel=”stylesheet” href=”dist/style.css”>

Next we will add three tailwind directives base, components and utilities to your CSS source file (e.g. /css/style.css) . Like so:

@tailwind base
@tailwind components
@tailwind utilities

Later, once the build process has been run within our webpack.config.js file, these directives will be replaced with a wide array of corresponding Tailwind CSS utility classes.

Next we will import our CSS file into our webpack entry file. Like so:

import "./css/style.css";

Note: In this example, our entry file will exist in a js folder (in the root directory) and is called scripts.js.

Your webpack config file

Now we have Tailwind CSS, PurgeCSS and our other tools installed and ready to use, you can go ahead and create a webpack config file. In the root directory of your web project create a file named webpack.config.js

To get you started below is a basic example of the the contents of webpack.config.js file, utilising Tailwind CSS, PurgeCSS and the other tools installed above.

Note: This file may be amended to fit your own needs. If you have no experience using or setting up a webpack config file, I recommend  the following article: A Beginner’s Guide to Webpack

const glob = require('glob')
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const purgeCSSPlugin = require('purgecss-webpack-plugin')
const postCSSPlugins = [require('tailwindcss'), require("autoprefixer"), require("cssnano")]

let cssConfig = {
  test: /\.css$/i,
  use: [
    "css-loader", 
    { 
      loader: "postcss-loader", 
      options: { 
        plugins: postCSSPlugins 
    }
   }
  ]
}

let config = {
  entry: {
    scripts: "./js/script.js"
  },
  plugins: [],
  module: {
    rules: [
      cssConfig
    ]
  }
}

cssConfig.use.unshift(MiniCssExtractPlugin.loader)
config.plugins.push(
  new MiniCssExtractPlugin({ filename: "style.css" }), 
  new purgeCSSPlugin({ 
    paths: glob.sync("/*.html", { nodir: true }),
    extractors: [
      {
        extractor: content => {
          const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []
          const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || []
          return broadMatches.concat(innerMatches)
        }
      }
    ]
  }), 
)

module.exports = config

Using Tailwind

Using Tailwind is as easy as adding utility classes to your respective HTML markup.

For example, the following code would output a medium red-coloured text, that is centred, with a font size of 1.125rem:

<p class="text-center text-red-500 text-lg">Hello world</p>

If you wanted to then increase the font-size on large desktop devices and above (with a minimum width of 1024px), you would simply introduce a responsive utility class e.g. “lg:text-xl”.

For example:

<p class="text-center text-red-500 text-lg lg:text-xl">Hello world</p>

Note: The npm run build command will need to be run, to see any changes. While you are developing I recommend commenting out the PurgeCSS portion of your code, just be sure to uncomment it before building your final CSS. A cleaner solution would be to look into the “The NPM Lifecycle Event variable” and wrap the PurgeCSS plugin code within an if statement, but for the sake of this blog post I have tried to keep things as simple as possible.

You may be wondering how I knew that the “text-xl” utility class would produce a font size of 1.125rem or how the responsive utility class “lg:text-xl” would respond to desktop devices with a width greater than 1024px. Well, this is where Tailwind’s extensive and brilliant documentation comes into play: tailwindcss.com/docs/. A simple search for “font size” and “responsive” yield both answers.

Likewise there are numerous Tailwind CSS  “cheat sheets”, which can often be the fastest way of finding out exactly what a utility class outputs. Nerd Cave’s is my usual go to: nerdcave.com/tailwind-cheat-sheet. It also allows you to select a specific version of Tailwind (in the bottom left hand corner), this can be very useful if you are using legacy versions of the framework, which support Internet Explorer 11.

Creating a Tailwind config file & customisation

Customising and extending the Tailwind CSS framework with your own utility classes is primarily done within the tailwind.config.js file. To create this file, run the following command from the command line:

npx tailwindcss init

Now you have a tailwind.config.js in your root directory, you can go ahead and start configuring it. Rather than me explain every way in which the framework can be configured, edited and ajusted, I will simply point you in the direction the official Tailwind CSS configuration documentation: tailwindcss.com/docs/configuration

Note: Extending the framework can also be achieved directly in your CSS, please see: tailwindcss.com/docs/adding-new-utilities

A quick final note

As mentioned above I highly recommend familiarising yourself with Tailwind’s official documentation, the “Functions & Directives” page particularly springs to mind. There is far more to Tailwind CSS than I have touched on in this blog post, but hopefully I have given you a solid foundation on how to set it up and how it can be combined with PurgeCSS.