A problem I’ve run into recently is updating some of my sites from version 3 to version 4 of tailwind.
There have been some big changes, especially with the way tailwind handles it’s configuration and how this has an effect on the use of the @apply directive.
From the looks of things some others have run into this problem as well.
From what I understand one of the causes of this is the way tailwind has altered the way it’s configuration is stored.
- Tailwind v3 originally would read it’s configuration from a js file such as
tailwind.config.cjs - Tailwind v4 instead now tends to use a css file as it’s primary input for configuration.
This in turn can have a nock on effect on the use of the @apply directive, part of the reason for this being that we no longer have a top level configuration file that’s referenced automatically.
There is supposed to be a backwards compatibility layer using the @config directive, but personally I didn’t have much luck getting this to work.
Creating a new tailwind CSS configuration file
As a first step we’re going to take the contents of tailwind.config.cjs and convert this into a tailwind-setts.css file.
I did manage to find an online converter but it’s mostly for converting colors, so doesn’t cover everything needed.
With this example I’ll be creating a file located at ./src/assets/tailwind-setts.css to store all the settings that were originally within the js file.
The first line of this file should start with the following to import all of the base / utils / components from within tailwind.
@import "tailwindcss";@config approach
Looking through the tailwind docs there is a @config directive we can add to try and import the settings from the original js file, your luck mary vary based on which framework you are using. For me with astro this didn’t seem to work though (perhaps because it’s a cjs file)
@import "tailwindcss";
@config "../../tailwind.config.cjs";Converting configuration to CSS approach
So the next approach is to try and convert things directly into css syntax
- https://tailwindcss.com/docs/functions-and-directives#theme-directive
- https://github.com/tailwindlabs/tailwindcss/discussions/15253
For me the original configuration looked something like this:
/** @type {import('tailwindcss').Config} */
const defaultTheme = require("tailwindcss/defaultTheme")
module.exports = {
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
darkMode: "class", // allows toggling dark mode manually
theme: {
extend: {
fontFamily: {
sans: ["Open Sans", "Poppins", "Roboto", "sans-serif", ...defaultTheme.fontFamily.sans],
bender: ["Bender"],
benderLight: ["BenderLight"],
},
},
},
plugins: [require("@tailwindcss/typography")],
}Converting this to ../../tailwind-setts.css
@import "tailwindcss";
@plugin '@tailwindcss/typography';
@custom-variant dark (&:where(.dark, .dark *));
@theme {
--font-sans: "Open Sans", "Poppins", "Roboto", "sans-serif";
--font-bender: "Bender";
--font-benderLight: "BenderLight";
}Configuration File Alias
Next we’re going to add an alias to the tailwind-setts.css file within package.json
"imports": {
"#tailwind-setts": "./src/assets/tailwind-setts.css"
}From this point forwards we can now use @reference "#tailwind-setts"; instead of trying to reference a relative path.
Switching over the references
Next we need to add a reference to this settings file wherever we were originally importing tailwind.
The easiest way to do this is to do a search though your source for @tailwind
Replace any of the following
@tailwind base;
@tailwind components;
@tailwind utilities;With a single one of these
@reference "#tailwind-setts";Changes for Astro
As a final step I needed to make some changes for use with astro. Although this will vary of course depending on your framework in use
Replace @astrojs/tailwind with @tailwindcss/vite
pnpm uninstall @astrojs/tailwind
pnpm add @tailwindcss/viteNext make some changes to the astro configuration astro.config.mjs.
Change the import line for tailwind.
-import tailwind from "@astrojs/tailwind"
+import tailwindcss from '@tailwindcss/vite';- Remove
tailwind(),from the integrations section - Add
plugins: [tailwindcss()]to the vite section
Layer Imports
One thing to watch out for which might impact your site.
If for any reason you were only importing some of the tailwind V3 layers such as avoiding the base layer
@tailwind components;
@tailwind utilities;This won’t work in Tailwind V4, all 3 layers are now imported with the line
@import "tailwindcss";
