Change header color 🎲 🎲

Jake Paris

in Maine, in 2024

Using Tailwind CSS in a WordPress Environment

To develop themes and plugins, I use the @wordpress/scripts package to do the build work. It comes with pre-defined webpack configs which work well for creating blocks and working within the requirements of the block editor. This post will assume you have familiarity with setting up your dev environment to make use of @wordpress/scripts.

Recently I decided to add TailWind CSS to a theme I was building, and it took me a little bit of time to get it set up correctly. I’ll share here how I eventually got it working. I’m going to talk about themes here, but I believe this same method should work with no modifications for plugins.

Add Tailwind CSS to your project

Install it as described in the tailwind docs:

npm i -D tailwindcss && npx tailwindcss init

Assuming your package.json is in your theme/plugin root, this will create a tailwind.config.js file in the root of your theme.

Configure Tailwind and Friends

Since we already have postcss in the WordPress webpack setup, we just need to add tailwind to that config.

Add a postcss config

Create a postcss.config.js file in your theme root with the following:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    ...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {} )
  }
}

Setting up the Build

This part was a bit tricky to get working. Apparently webpack doesn’t work perfectly well with the default config tailwind gives you. It has to do with watching directories and also limiting by filetype. So the default tailwind config would hit an infinitely looping build while watching. This can be fixed by using fast-glob in the content value. So first we need to add that to our project:

npm i -D fast-glob

Configuring Tailwind

To scan any top-level template php or html files we use ./*.{php,html}

To scan all React-based blocks (which live in the src directory), we use ./src/**/*.js.

And then we also want to check all subdirectories for php and html templates. But we need to be sure that tailwind isn’t scanning the webpack output directory for classes to prevent infinite loops when either js or perhaps the render.php is compiled. To prevent this, I added ./!(build)/**/*.{php,html} which tells tailwind to scan any php/html file in any subdirectory recursively, as long as it isn’t the build directory.

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: require('fast-glob').sync([
    "./src/**/*.js",
    "./*.{php,html}",
    "./!(build)/**/*.{php,html}",
  ]),
  theme: {},
    extend: {},
  },
  plugins: [],
}

Add Tailwind to your CSS

Lastly, we want to add the tailwind utility classes, etc to our css. In your main css file (whichever one tailwind is writing to, in my case I have a public.scss file as my main theme css) add the tailwind special directives to the top:

@tailwind base;
@tailwind components;
@tailwind utilities;

Done

That’s it. Now when you run either the dev or build commands that come with @wordpress/scripts, tailwind will do it’s thing. In addition to its base stuff, any of its classnames you’ve used in any of your html, js, or php templates, will automatically be added to the output css file.