Skip to content

Tailwind CSS - Using with Preprocessors

# Tailwind CSS: Preprocessors and Modern Workflows

Section titled “# Tailwind CSS: Preprocessors and Modern Workflows”

At its core, Tailwind CSS is a PostCSS plugin. This means it’s designed to fit seamlessly into the modern CSS toolchain. While you can use it with traditional preprocessors like Sass or Less, the most powerful and efficient workflow involves leveraging the PostCSS ecosystem directly.

Best Practice: For new projects, we strongly recommend using PostCSS as your primary CSS processing tool. This leads to faster builds, simpler configuration, and avoids compatibility issues.

Instead of using a separate preprocessor, you can add features like imports and nesting using dedicated PostCSS plugins. This is the approach used by most modern frontend frameworks (like Vite, Next.js, and SvelteKit).

Start by setting up Tailwind in your project. If you’re using a framework, follow its specific guide. For a standalone project, use the Tailwind CLI:

# 1. Install Tailwind CSS
npm install -D tailwindcss postcss autoprefixer
# 2. Create your configuration files
npx tailwindcss init -p

This creates tailwind.config.js and postcss.config.js.

Now, let’s add common preprocessor features using PostCSS plugins.

Imports (@import) To combine multiple CSS files at build time, use postcss-import.

npm install -D postcss-import

Nesting For nested CSS rules, use the official tailwindcss/nesting plugin. It’s a compatibility layer that ensures nesting works correctly with Tailwind’s syntax.

# `tailwindcss/nesting` is bundled with `tailwindcss`, so no extra install needed.

The order of plugins matters. postcss-import and tailwindcss/nesting must run before tailwindcss.

postcss.config.js
module.exports = {
plugins: {
'postcss-import': {}, // Handles @import statements
'tailwindcss/nesting': {}, // Handles CSS nesting
'tailwindcss': {}, // Processes Tailwind directives and classes
'autoprefixer': {}, // Adds vendor prefixes for browser compatibility
},
}

With this setup, you can organize your CSS logically.

src/input.css
/* 1. Import Tailwind's base, components, and utilities */
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
/* 2. Import your own custom component styles */
@import "./components/buttons.css";
@import "./components/cards.css";
/* 3. Add any top-level custom base styles */
body {
@apply bg-gray-100 text-gray-800;
}
src/components/buttons.css
.btn-primary {
@apply px-4 py-2 bg-blue-600 text-white rounded-md;
&:hover {
@apply bg-blue-700;
}
}

## Variables: theme() vs. CSS Custom Properties

Section titled “## Variables: theme() vs. CSS Custom Properties”

You have two powerful options for variables:

  • theme() function: Use this to access your design tokens from tailwind.config.js directly in your CSS. This is the best way to maintain consistency with your design system.
  • CSS Custom Properties (--*): Use these for dynamic values that might need to be changed by JavaScript in the browser, or for values that are outside your theme.
:root {
--header-height: 60px; /* A dynamic value */
}
.header {
height: var(--header-height);
background-color: theme('colors.slate.800'); /* A theme value */
}

## Using Traditional Preprocessors (Sass/Less)

Section titled “## Using Traditional Preprocessors (Sass/Less)”

If you must integrate Tailwind into a project that already uses a preprocessor like Sass, it is possible. The key is to process your Sass/Less files first, and then pipe the output to PostCSS.

Your build process should look like this: Sass File -> Sass Compiler -> CSS Output -> PostCSS (with Tailwind) -> Final CSS.

Be aware of syntax conflicts. For example, Sass has its own @apply rule, which has been deprecated. The most common issue is using Tailwind’s !important modifier with @apply inside a Sass file, which requires interpolation:

// Inside a .scss file
.my-class {
// You must wrap `!important` in `#{}` for Sass to ignore it
@apply text-red-500 #{!important};
}

Due to these small but frustrating quirks, migrating to a pure PostCSS setup is recommended for the best development experience.