Using Tailwind CSS in a WordPress Environment
Written on January 25, 2023
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.