How to Set Up Tailwind CSS in a SPFx Project

Published May 01 2021 01:48 AM 2,167 Views
Occasional Contributor

In the State of CSS 2020 survey, the Tailwind CSS becomes the number 1 CSS Framework in terms of Satisfaction and Interest in the last 2 years. It also gets the awards for The Most Adopted Technology. It seems a lot of developers like this framework. Based on my experience, this framework can help us rapidly build UI by reducing complexity when styling the UI.

 

State of CSS 2020 Survey.pngState of CSS 2020 Survey — CSS Frameworks result

 

In this article, I will share my setup to use the Tailwind CSS in a SharePoint Framework (SPFx) project.

 

Prepare the SPFx Project

Prepare your SPFx project. I use a newly generated SPFx project (v1.11) but you can also use your existing SPFx project.

 

Install Modules

Install all modules needed by executing the command below:

npm install tailwindcss@1.9.6 postcss postcss-cli postcss-import @fullhuman/postcss-purgecss gulp-postcss autoprefixer@9.8.6 -D

 

Initialize Tailwind CSS and PostCSS

Initialize Tailwind CSS by executing the command below:

npx tailwind init -p --full

The command will create the tailwind.config.js in the project’s base directory. The file contains the configurations, such as colors, themes, media queries, and so on.

The command will also create the postcss.config.js file. We need PostCSS because we will use Tailwind CSS as a PostCSS plugin.

 

Inject Tailwind CSS Components and Utilities

We need to create a CSS file that will be used to import Tailwind CSS styles.

  • Create an assets folder in the project’s base directory
  • Create a tailwind.css file in the assets folder
  • Add the following lines of code to the file:
@import "tailwindcss/components";
@import "tailwindcss/utilities";

 

Add Gulp Subtask for Processing Tailwind CSS

We need to add the Tailwind CSS build process to our SPFx build process.

  • Open the gulpfile.js
  • Add the following lines of code to the file (before the build.initialize(require(‘gulp’)); line):
const postcss = require("gulp-postcss");
const atimport = require("postcss-import");
const purgecss = require("@fullhuman/postcss-purgecss");
const tailwind = require("tailwindcss");
const tailwindcss = build.subTask(
"tailwindcss",
function (gulp, buildOptions, done) {
gulp
.src("assets/tailwind.css")
.pipe(
postcss([
atimport(),
tailwind("./tailwind.config.js"),
...(buildOptions.args.ship
? [
purgecss({
content: ["src/**/*.tsx"],
defaultExtractor: (content) =>
content.match(/[\w-/:]+(?<!:)/g) || [],
}),
]
: []),
])
)
.pipe(gulp.dest("assets/dist"));
done();
}
);
build.rig.addPreBuildTask(tailwindcss);

The code will add the tailwindcss subtask to the SPFx Gulp Build task. It will also purge (remove unused styles) the Tailwind CSS for build with ship flag:

gulp build --ship

or

gulp bundle --ship

 

Add Reference to The Generated Tailwind CSS

We need to add reference the generated Tailwind CSS by adding the import code in your main .ts webpart file:

import '../../../assets/dist/tailwind.css';

 

That’s it!

Now you can use Tailwind CSS utilities in your SPFx project.

 

Result

You might be familiar with the below result except it’s not using styles from the 74-lines scss/css file anymore.

 

REsult.png

 

Below is the updated React component that’s using the Tailwind CSS utility classes for styling.

Latest code.png

 

You can see the full code changes in my Github repository.

%3CLINGO-SUB%20id%3D%22lingo-sub-2313192%22%20slang%3D%22en-US%22%3EHow%20to%20Set%20Up%20Tailwind%20CSS%20in%20a%20SPFx%20Project%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-2313192%22%20slang%3D%22en-US%22%3E%3CP%20class%3D%22graf%20graf--p%22%3EIn%20the%20%3CA%20class%3D%22markup--anchor%20markup--p-anchor%22%20href%3D%22https%3A%2F%2F2020.stateofcss.com%2Fen-US%2Ftechnologies%2Fcss-frameworks%2Fcss_frameworks_experience_ranking%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20data-href%3D%22https%3A%2F%2F2020.stateofcss.com%2Fen-US%2Ftechnologies%2Fcss-frameworks%2Fcss_frameworks_experience_ranking%22%3EState%20of%20CSS%202020%20survey%3C%2FA%3E%2C%20the%20%3CA%20class%3D%22markup--anchor%20markup--p-anchor%22%20href%3D%22https%3A%2F%2Ftailwindcss.com%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20data-href%3D%22https%3A%2F%2Ftailwindcss.com%2F%22%3ETailwind%20CSS%3C%2FA%3E%20becomes%20the%20number%201%20CSS%20Framework%20in%20terms%20of%20%3CSTRONG%3ESatisfaction%3C%2FSTRONG%3E%20and%20%3CSTRONG%3EInterest%3C%2FSTRONG%3E%20in%20the%20last%202%20years.%20It%20also%20gets%20the%20awards%20for%20%3CSTRONG%20class%3D%22markup--strong%20markup--p-strong%22%3EThe%20Most%20Adopted%20Technology%3C%2FSTRONG%3E.%20It%20seems%20a%20lot%20of%20developers%20like%20this%20framework.%20Based%20on%20my%20experience%2C%20this%20framework%20can%20help%20us%20rapidly%20build%20UI%20by%20reducing%20complexity%20when%20styling%20the%20UI.%3C%2FP%3E%0A%3CFIGURE%20class%3D%22graf%20graf--figure%22%3E%0A%3CDIV%20id%3D%22tinyMceEditorAri%20Gunawan_0%22%20class%3D%22mceNonEditable%20lia-copypaste-placeholder%22%3E%26nbsp%3B%3C%2FDIV%3E%0A%3CP%20class%3D%22lia-align-center%22%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22State%20of%20CSS%202020%20Survey.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F277241iDC0EFE176EA24C94%2Fimage-size%2Flarge%3Fv%3Dv2%26amp%3Bpx%3D999%22%20role%3D%22button%22%20title%3D%22State%20of%20CSS%202020%20Survey.png%22%20alt%3D%22State%20of%20CSS%202020%20Survey.png%22%20%2F%3E%3C%2FSPAN%3E%3CEM%3EState%20of%20CSS%202020%20Survey%E2%80%8A%E2%80%94%E2%80%8ACSS%20Frameworks%20result%3C%2FEM%3E%3C%2FP%3E%0A%3C%2FFIGURE%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EIn%20this%20article%2C%20I%20will%20share%20my%20setup%20to%20use%20the%20Tailwind%20CSS%20in%20a%20SharePoint%20Framework%20(SPFx)%20project.%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%3CSTRONG%20class%3D%22markup--strong%20markup--p-strong%22%3EPrepare%20the%20SPFx%20Project%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EPrepare%20your%20SPFx%20project.%20I%20use%20a%20newly%20generated%20%3CA%20class%3D%22markup--anchor%20markup--p-anchor%22%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fsharepoint%2Fdev%2Fspfx%2Fweb-parts%2Fget-started%2Fbuild-a-hello-world-web-part%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%20data-href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fsharepoint%2Fdev%2Fspfx%2Fweb-parts%2Fget-started%2Fbuild-a-hello-world-web-part%22%3ESPFx%20project%3C%2FA%3E%20(v1.11)%20but%20you%20can%20also%20use%20your%20existing%20SPFx%20project.%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%3CSTRONG%20class%3D%22markup--strong%20markup--p-strong%22%3EInstall%20Modules%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EInstall%20all%20modules%20needed%20by%20executing%20the%20command%20below%3A%3C%2FP%3E%0A%3CPRE%20class%3D%22graf%20graf--pre%22%3Enpm%20install%20tailwindcss%401.9.6%20postcss%20postcss-cli%20postcss-import%20%40fullhuman%2Fpostcss-purgecss%20gulp-postcss%20autoprefixer%409.8.6%20-D%3C%2FPRE%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%3CSTRONG%20class%3D%22markup--strong%20markup--p-strong%22%3EInitialize%20Tailwind%20CSS%20and%20PostCSS%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EInitialize%20Tailwind%20CSS%20by%20executing%20the%20command%20below%3A%3C%2FP%3E%0A%3CPRE%20class%3D%22graf%20graf--pre%22%3Enpx%20tailwind%20init%20-p%20--full%3C%2FPRE%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EThe%20command%20will%20create%20the%20%3CEM%20class%3D%22markup--em%20markup--p-em%22%3Etailwind.config.js%20%3C%2FEM%3Ein%20the%20project%E2%80%99s%20base%20directory.%20The%20file%20contains%20the%20configurations%2C%20such%20as%20colors%2C%20themes%2C%20media%20queries%2C%20and%20so%20on.%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EThe%20command%20will%20also%20create%20the%20%3CEM%20class%3D%22markup--em%20markup--p-em%22%3Epostcss.config.js%3C%2FEM%3E%20file.%20We%20need%20PostCSS%20because%20we%20will%20use%20Tailwind%20CSS%20as%20a%20PostCSS%20plugin.%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%3CSTRONG%20class%3D%22markup--strong%20markup--p-strong%22%3EInject%20Tailwind%20CSS%20Components%20and%20Utilities%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EWe%20need%20to%20create%20a%20CSS%20file%20that%20will%20be%20used%20to%20import%20Tailwind%20CSS%20styles.%3C%2FP%3E%0A%3CUL%20class%3D%22postList%22%3E%0A%3CLI%20class%3D%22graf%20graf--li%22%3ECreate%20an%20a%3CEM%20class%3D%22markup--em%20markup--li-em%22%3Essets%3C%2FEM%3E%20folder%20in%20the%20project%E2%80%99s%20base%20directory%3C%2FLI%3E%0A%3CLI%20class%3D%22graf%20graf--li%22%3ECreate%20a%20%3CEM%20class%3D%22markup--em%20markup--li-em%22%3Etailwind.css%20%3C%2FEM%3Efile%20in%20the%20%3CEM%20class%3D%22markup--em%20markup--li-em%22%3Eassets%20%3C%2FEM%3Efolder%3C%2FLI%3E%0A%3CLI%20class%3D%22graf%20graf--li%22%3EAdd%20the%20following%20lines%20of%20code%20to%20the%20file%3A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CPRE%20class%3D%22graf%20graf--pre%22%3E%3CA%20class%3D%22markup--anchor%20markup--pre-anchor%22%20title%3D%22Twitter%20profile%20for%20%40import%22%20href%3D%22http%3A%2F%2Ftwitter.com%2Fimport%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20data-href%3D%22http%3A%2F%2Ftwitter.com%2Fimport%22%3E%40import%3C%2FA%3E%20%22tailwindcss%2Fcomponents%22%3B%3CBR%20%2F%3E%3CA%20class%3D%22markup--anchor%20markup--pre-anchor%22%20title%3D%22Twitter%20profile%20for%20%40import%22%20href%3D%22http%3A%2F%2Ftwitter.com%2Fimport%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%20data-href%3D%22http%3A%2F%2Ftwitter.com%2Fimport%22%3E%40import%3C%2FA%3E%20%22tailwindcss%2Futilities%22%3B%3C%2FPRE%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3E%3CSTRONG%20class%3D%22markup--strong%20markup--p-strong%22%3EAdd%20Gulp%20Subtask%20for%20Processing%20Tailwind%20CSS%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%20class%3D%22graf%20graf--p%22%3EWe%20need%20to%20add%20the%20Tailwind%20CSS%20build%20process%20to%20our%20SPFx%20build%20process.%3C%2FP%3E%0A%3CUL%20class%3D%22postList%22%3E%0A%3CLI%20class%3D%22graf%20graf--li%22%3EOpen%20the%20%3CEM%20class%3D%22markup--em%20markup--li-em%22%3Egulpfile.js%3C%2FEM%3E%3C%2FLI%3E%0A%3CLI%20class%3D%22graf%20graf--li%22%3EAdd%20the%20following%20lines%20of%20code%20to%20the%20file%20(before%20the%20%3CEM%20class%3D%22markup--em%20markup--li-em%22%3Ebuild.initialize(require(%E2%80%98gulp%E2%80%99))%3B%3C%2FEM%3E%20line)%3A%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CPRE%20class%3D%22graf%20graf--pre%22%3Econst%20postcss%20%3D%20require(%22gulp-postcss%22)%3B%3CBR%20%2F%3Econst%20atimport%20%3D%20require(%22postcss-import%22)%3B%3CBR%20%2F%3Econst%20purgecss%20%3D%20require(%22%40fullhuman%2Fpostcss-purgecss%22)%3B%3CBR%20%2F%3Econst%20tailwind%20%3D%20require(%22tailwindcss%22)%3B%3C%2FPRE%3E%0A%3CPRE%20class%3D%22graf%20graf--pre%22%3Econst%20tailwindcss%20%3D%20build.subTask(%3CBR%20%2F%3E%20%20%20%22tailwindcss%22%2C%3CBR%20%2F%3E%20%20%20function%20(gulp%2C%20buildOptions%2C%20done)%20%7B%3CBR%20%2F%3E%20%20%20%20%20%20gulp%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20.src(%22assets%2Ftailwind.css%22)%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20.pipe(%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20postcss(%5B%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20atimport()%2C%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20tailwind(%22.%2Ftailwind.config.js%22)%2C%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20...(buildOptions.args.ship%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3F%20%5B%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20purgecss(%7B%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content%3A%20%5B%22src%2F**%2F*.tsx%22%5D%2C%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20defaultExtractor%3A%20(content)%20%3D%26gt%3B%3CBR%20%2F%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20content.match(%2F%5B%5Cw-%2F%3A%5D%2B(%3F%3C%2FPRE%3E%3C%2FLINGO-BODY%3E
Co-Authors
Version history
Last update:
‎May 01 2021 01:48 AM
Updated by: