Tailwind CSS v4 and SCSS combination

Table of Contents
Introduction
What is Tailwind CSS?
Tailwind CSS is a utility-first CSS framework. Unlike frameworks like Bootstrap, which come with pre-built UI components such as "buttons" and "navigation bars," Tailwind CSS is characterized by a style where you combine utility classes to build designs. You can efficiently create web pages by simply combining the provided utility classes without having to write new, custom CSS files.
Tailwind CSS example
<button class="px-4 py-2 bg-blue-500 text-white rounded">ボタン</button>
px-4
: 1rem (16px) of horizontal paddingpy-2
: 0.5rem (8px) of vertical paddingbg-blue-500
: Background color is blue (#3B82F6
,500
indicates color intensity)text-white
: Text color is white (#FFFFFF
)rounded
: Rounded corners (border-radius: 0.25rem
)
Disadvantages of Tailwind CSS and their solutions
While Tailwind CSS allows for efficient page creation, an increase in utility class specifications can lead to bloated class
attributes in HTML files, making the markup less readable. Therefore, there are cases where you might want to differentiate usage: define frequently used common style combinations as classes in a CSS file, and use utility classes for page-specific styles. Tailwind CSS provides the @apply
directive for this purpose, allowing multiple styles to be grouped and defined as a class in a CSS file.
@apply
directive example
.btn {
@apply px-4 py-2 bg-blue-500 text-white rounded;
}
<button class="btn">ボタン</button>
Combining Tailwind CSS with SCSS, and the advent of Version 4
The @apply
directive is a powerful feature on its own, but there are cases where using SCSS (Sass) variables, nesting, and control structures for CSS can lead to higher reusability and maintainability. Therefore, combining Tailwind CSS with SCSS was one solution.
However, with the advent of Tailwind CSS v4, the situation has changed. The official Tailwind documentation states:
Sass, Less, and Stylus Tailwind CSS v4.0 is a full-featured CSS build tool designed for a specific workflow, and is not designed to be used with CSS preprocessors like Sass, Less, or Stylus.
Think of Tailwind CSS itself as your preprocessor — you shouldn't use Tailwind with Sass for the same reason you wouldn't use Sass with Stylus.
Since Tailwind is designed for modern browsers, you actually don't need a preprocessor for things like nesting or variables, and Tailwind itself will do things like bundle your imports and add vendor prefixes.
(Google Translate) Tailwind CSS v4.0 is a full-featured CSS build tool designed for a specific workflow, and is not designed to be used with CSS preprocessors like Sass, Less, or Stylus.
Think of Tailwind CSS itself as your preprocessor — you shouldn't use Tailwind with Sass for the same reason you wouldn't use Sass with Stylus.
Since Tailwind is designed for modern browsers, you actually don't need a preprocessor for things like nesting or variables, and Tailwind itself will do things like bundle your imports and add vendor prefixes.
It explicitly states, "you shouldn't use Tailwind with Sass."
- Sass
$
variables → can be replaced by CSS standardcustom properties (CSS variables)
or Tailwind v4's@theme
- Sass nesting → CSS standard nesting can be used in modern browsers
Considering these situations, the argument seems to be that preprocessors are no longer necessary, and everything needed can be handled by Tailwind alone. While I don't fully grasp yet how much of what Sass can do is possible with Tailwind CSS, the policy of "if you use Tailwind, you should break away from Sass" is clearly stated.
However, it's not realistic to migrate existing Sass assets to Tailwind overnight. Therefore, it's more practical to continue using the combination of Tailwind CSS v4 and SCSS as a transition period, gradually moving towards a style that doesn't use SCSS.
The following section explains how to combine Tailwind CSS v4 with SCSS.
Prerequisites
Node.js
is installed (as of this writing, v22.19.0 (LTS version) is used)
node -v
v22.19.0
- Verified operation with Visual Studio 2022, Visual Studio Code
Basic Structure
The basic concept remains the same as v3.
scss → transpile with sass
→ intermediate css → compile with tailwind
→ final css
This is the process.
Let's take an SCSS file that contains the following three components as an example.
- hoge.scss
@use "component-a.scss";
@use "component-b.scss";
@use "component-c.scss";
- Conversion Flow
flowchart TD CA(component-a.scss) -.-> X CB(component-b.scss) -.-> X CC(component-c.scss) -.-> X X(hoge.scss) -->| npx sass | I[temp.css] ENTRY(tailwind-entry.css) --> T I --> T["tailwind.css<br>(Intermediate CSS)"] T --> | npx @tailwindcss/cli | CSS["hoge.css<br>(Final CSS)"]
Installing Frontend Tools
Adding package.json to the project
Navigate to your project folder and run npm init
.
cd [プロジェクトフォルダ]
npm init -y
package.json
will be created directly in your project folder.
Installing Sass
npm install sass --save-dev
Installing Tailwind CSS
npm install tailwindcss @tailwindcss/cli --save-dev
In Tailwind v4, the command-line tool package has changed from tailwindcss
to @tailwindcss/cli
.
Configuration
In Tailwind v4, the functionality to create the configuration file tailwind.config.js
using npx tailwindcss init -p
has been removed.
Instead of a JS file, a CSS file containing the @import "tailwindcss"
directive below serves as both the configuration file and the entry file.
(The @tailwind
directive from v3 and earlier has been deprecated.)
@import "tailwindcss";
When compiling with Tailwind, it's sufficient for the input file to contain @import "tailwindcss"
. However, if the input file contains @import "tailwindcss"
when compiling with Sass, an error like the following occurs:
>npx sass wwwroot/css/hoge.scss wwwroot/css/tailwind.css
Error: Can't find stylesheet to import.
╷
1 │ @import "tailwindcss";
│ ^^^^^^^^^^^^^
╵
wwwroot\css\hoge.scss 1:10 root stylesheet
This is because the Tailwind directive changed from @tailwind
to @import
. Sass tries to process @import
and attempts to read a _tailwindcss.scss
file, resulting in a "file not found" error. To avoid this error, when using Sass in conjunction, it's necessary to separate the Tailwind configuration into a different file to prevent Sass from throwing an error.
flowchart TD X(hoge.scss) -->| npx sass | I[temp.css] ENTRY("tailwind-entry.css<br>(Configuration/Entry File)") --> | cat | T I --> | cat | T["tailwind.css<br>(Intermediate CSS)"]
- tailwind-entry.css
@import "tailwindcss";
The Tailwind @import
directive should be placed in a separate file (tailwind-entry.css), then combined with the Sass transpiled file to create the input file for Tailwind.
Build
1Compile hoge.scss to temp.css
flowchart TD CA(component-a.scss) -.-> X CB(component-b.scss) -.-> X CC(component-c.scss) -.-> X X(hoge.scss) -->| npx sass | I[temp.css]
npx sass wwwroot/css/hoge.scss wwwroot/css/temp.css
npx sass
: Command to compile Sass (SCSS files)- wwwroot/css/hoge.scss: Input file (SCSS file)
- wwwroot/css/temp.css: Output file (CSS file)
2Combine tailwind-entry.css and temp.css to create tailwind.css
flowchart TD ENTRY(tailwind-entry.css) --> T["tailwind.css<br>(Intermediate CSS)"] I[temp.css] --> T
cat wwwroot/css/tailwind-entry.css wwwroot/css/temp.css > wwwroot/css/tailwind.css
For Windows environments:
type wwwroot\\css\\tailwind-entry.css wwwroot\\css\\temp.css > wwwroot\\css\\tailwind.css
3Compile tailwind.css to hoge.css
flowchart TD T["tailwind.css<br>(Intermediate CSS)"] --> | npx @tailwindcss/cli | CSS["hoge.css<br>(Final CSS)"]
npx @tailwindcss/cli -i wwwroot/css/tailwind.css -o wwwroot/css/hoge.css
npx @tailwindcss/cli
: Build CSS with Tailwind CLI- -i wwwroot/css/tailwind.css: Input file
- -o wwwroot/csshoge.css: Output file (final CSS to use)
Automatic Build
To automatically execute Tailwind compilation when file changes are detected, add the --watch
option.
npx @tailwindcss/cli -i wwwroot/css/tailwind.css -o wwwroot/css/hoge.css --watch
However, this won't run when an scss
file is modified. sass
also has a --watch
option, but since files need to be concatenated, --watch
alone is insufficient. There are several solutions, but here we introduce a method using extensions.
Add npm scripts to package.json
As preparation for implementing automatic builds, add npm scripts so that a series of commands can be executed with a single command.
- package.json
{
"devDependencies": {
"@tailwindcss/cli": "^4.1.13",
"sass": "^1.92.0",
"tailwindcss": "^4.1.13"
},
"scripts": {
"build:css": "npx sass wwwroot/css/hoge.scss wwwroot/css/temp.css --no-source-map && type wwwroot\\css\\tailwind-entry.css wwwroot\\css\\temp.css > wwwroot\\css\\tailwind.css && npx @tailwindcss/cli -i wwwroot/css/tailwind.css -o wwwroot/css/hoge.css"
}
}
Confirm that the series of commands are executed with the following command.
npm run build:css
For Visual Studio 2022
For Visual Studio 2022, use Tailwind CSS VS2022 Editor Support. This extension provides not only Tailwind builds but also Tailwind auto-completion (IntelliSense) within Razor, HTML, and CSS files, as well as automatic sorting of class names. To perform automatic builds on file save, configure the extension settings as shown below (Figure 1.).
Build type: OnSave Execute build upon saving the file
OnSave trigger: file extensions: .css;.scss;.html;.cshtml File extensions (semicolon-separated) for which to execute build on save
Build script: build:css Name of the npm script added to package.json
Override build: True If not set to True, the default
npx @tailwindcss/cli
will be executed afterbuild:css
Changing the extension's configuration file In addition to the settings screen, an extension configuration file named
tailwind.extension.json
is automatically created directly in the project folder. Configure it as follows:
{
"$schema": "https://raw.githubusercontent.com/theron-wang/VS2022-Editor-Support-for-Tailwind-CSS/refs/heads/main/tailwind.extension.schema.json",
"BuildFiles": [
{
"Input": "wwwroot\\css\\tailwind-entry.css",
"Output": "",
"Behavior": "Default"
}
],
"PackageConfigurationFile": "package.json",
"CustomRegexes": {
"Razor": {
"Override": false,
"Values": []
},
"HTML": {
"Override": false,
"Values": []
},
"JavaScript": {
"Override": false,
"Values": []
}
},
"UseCli": false
}
- "PackageConfigurationFile": "package.json"
It is null by default. This setting is required because the npm script name will not be recognized if
package.json
is not configured.
Other settings can remain at their defaults. (The BuildFiles > Input
section is automatically set when the configuration file is generated.)
With these settings, builds will be automatically executed when files are saved.
For Visual Studio Code
For building, use the extension Run on Save @emeraldwalk.
The configuration file will be as follows:
- .vscode\settings.json
{
"emeraldwalk.runonsave": {
"commands": [
{
"match": ".*\\.(css|scss|html|cshtml)$",
"cmd": "npm run build:css"
}
]
}
}
Auto-completion (IntelliSense) will be enabled by installing Tailwind CSS IntelliSense.
Summary
Tailwind CSS v4 is designed to align with modern CSS specifications and browser advancements, diminishing the need for preprocessors like Sass. However, migrating existing SCSS assets within a short period may not be realistic. Therefore, for the time being, it's a sensible option to maintain the conventional build process that integrates SCSS → CSS → Tailwind, while gradually transitioning to Tailwind's new features.
While Sass will not disappear immediately, CSS functionalities are continually expanding, and many of the roles previously handled by Sass are being replaced by native specifications. By being aware of this trend, you can move towards a simpler and more future-proof style design.