loading...
Cover image for Angular 8 + Tailwind CSS Guide (Updated for Angular 9)

Angular 8 + Tailwind CSS Guide (Updated for Angular 9)

seankerwin profile image Sean Kerwin Updated on ・3 min read

So, I've found a lot of crappy guides on the internet about how to integrate TailwindCSS with Angular 8, a lot of them involve some nasty hacks that I think are basically, shit. I've collated some information from various sources online to show you how I go about implementing TailwindCSS with Angular 8. If you're reading this and you don't know what TailwindCSS is, two things, one, where the hell have you been the past few years and two, go to tailwindcss.com and feast in the amazingness (is that even a word) that is Tailwind.

We'll be utilising the @angular-builders/custom-webpack package which will essentially allow us to tailor the webpack build to add tailwind into the build process.

First things first, install the following:

npm i tailwindcss postcss-scss postcss-import postcss-loader @angular-builders/custom-webpack -D

Next you need to open up your Angular project, I'm going to assume you're using sass, as well, why the fuck not?

Open your styles.scss file and add the following at the top.

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

Next, you need to create the tailwind config file, to do so, open your terminal and smash in the following (inside the directory of your app of course).

npx tailwind init

Now we need to extend the webpack config, first, start by creating webpack.config.js at the root of your project, this is what it should look like

module.exports = {
    module: {
        rules: [
            {
                test: /\.scss$/,
                loader: 'postcss-loader',
                options: {
                    ident: 'postcss',
                    syntax: 'postcss-scss',
                    plugins: () => [
                        require('postcss-import'),
                        require('tailwindcss'),
                        require('autoprefixer'),
                    ]
                }
            }
        ]
    }
};

Once you've added that, modify the angular.json file to tell it to use the custom builder and config file.

{
  "architect": {
    "build": {
      "builder": "@angular-builders/custom-webpack:browser",
      "options": {
        "customWebpackConfig": {
          "path": "./webpack.config.js"
        }
      }
    },
    "serve": {
      "builder": "@angular-builders/custom-webpack:dev-server",
      "options": {
        "customWebpackConfig": {
          "path": "./webpack.config.js"
        }
      }
    }
  }
}

Now we're all up and ready to rumble, add some tailwind classes to an object and run

npm start

Extra

The whole point of Tailwind is to create custom utilities, you can do so by doing the following:

Modify your styles.scss and add 2 new custom imports.

@import 'tailwindcss/base';
@import 'tailwindcss/components'; 
@import './custom-tailwind/custom-components.css'; // added
@import 'tailwindcss/utilities';
@import './custom-tailwind/custom-utilities.css'; // added

Make sure that they're added in the exact order above.

You can now create a folder inside the src directory called custom-tailwind
Inside this, you create the 2 files the same names as above, now you can create custom reusable utilities and components, for example:

custom-components.css

.btn {
  @apply px-4;
  @apply py-2;
  @apply rounded;
  @apply bg-indigo-500;
  @apply text-white;
  transition: 200ms;
}

.btn:hover {
  @apply bg-indigo-600;
}

And now anywhere you want a button, just give it the class .btn and it will apply all the tailwind classes.

For custom-utilities.css, you can do the following:

.rotate-0 {
    transform: rotate(0deg);
}
.rotate-90 {
    transform: rotate(90deg);
}
.rotate-180 {
    transform: rotate(180deg);
}
.rotate-270 {
    transform: rotate(270deg);
}

And now anywhere, you can just call these classes. Neat huh!

Enjoy the power that is TailwindCSS + Angular 8!

Update:

I realise this is a repeated post, for some reason I had 3 dev.to accounts (god knows why) and this is the account I wanted to use, so I deleted this post along with the other account and re-created it here.

Update 2:

This also works the same way with Angular 9, I have this working using angular version "@angular/core": "~9.0.0",

Posted on Nov 12 '19 by:

seankerwin profile

Sean Kerwin

@seankerwin

I'm an intuative and determined software developer who loves to code, I can always find a solution to the problem even if its a stack/language I'm not familiar with. My passion is front-end/UI/UX

Discussion

markdown guide
 

Hi,

Is it possible to use tailwind @apply function inside of component specific style files? Instead of global one?

Currently my component html might become overloaded of classes and is harder to read.
Instead I could give component context meaningful classes to component HTML elements, and style them with @apply function inside of component stylesheet.

Do you know if it is possible?

Thanks, nice article 👍

 

As far as i know, I haven't found a way to use @apply inside a component specific style file. this is because webpack needs to know the file to compile into normal CSS.

There's nothing wrong with having loads of css classes inside HTML, some of mine are full of it, pointless making a class if im only going to use it once, or it's a specific instance i need styling. things like buttons and what not just go inside the custom-components.

If you do find a way of doing it, let me know!

Happy coding!

 

Did you find an answer to this? Without it Tailwind is unusable on any significant project.

 

I have used Tailwind on some Huge projects...

In fact, apart from some reusable items in my global styles.scss like .btn classes and input classes, all my "component" css files are empty... as i use the tailwind classes within the HTML. I have no need to write component specific styling.

 

But you can indeed use @apply inside a component's style file, what am I missing? could you talk us through the issue you're facing please.

Unfortunately not, because tailwind is built through custom webpack process, adding component's styles to that is difficult and not supported.

I have actually just checked and this works fine for me, using scss, postcss-loader for webpack, and "tailwindcss": "^1.4.4".
dev-to-uploads.s3.amazonaws.com/i/...

sorry new here don't know why i cant attach photos.

Same for me. Works just fine when I've followed the implementation described in tis article.

 
 

I just tried this, and while it seemed to work just fine, it appears to have removed the configurations sections under build and serve in the angular.json file. I'm still learning, but is this expected or might I have done something wrong? I'm not sure if customWebpackConfig and configurations live and work in harmony, or if the former replaces the later.

 

I saw this too. Not sure if it's expected but you could probably add them back to the config yourself. What do you say @Sivuyile?

Thanks for writing the package, btw!

 

I have only just seen this. I've just tested it out and it works perfectly! Good work.
Mind if I fork it to add TailwindUI for those of us that use that too?

 

Data path "" should NOT have additional properties(customWebpackConfig).

 

Go to angular.json and modify builder in build and serve sections:

"projects": {
...
"example-app": {
...
"architect": {
...
"build": {
"builder": "@angular-builders/custom-webpack:browser"
"options": {
...
}

 

Then get error:
Schema validation failed with the following errors:
Data path "" should NOT have additional properties(browserTarget).

 

I think I'm missing something. I have the following code in my angular app.

<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
  <div class="bg-gray-400">1</div>
  <div class="bg-gray-400">2</div>
  <div class="bg-blue-300">3</div>
</div>

In my angular app the grid doesn't work when I look at it in my dev inspector the grid classes don't seem to be there. The same code in a codepen and the class is there. So I'm assuming somehow the grid classes didn't get installed in my angular app. Other tailwind classes (ie bg-gray-400) are working. Anyone have any suggestions on how to fix this?

 

Code looks fine. What version of tailwind are you using? I’m using 1.2 and grids work fine like that.

 
` "tailwindcss": "^1.2.0",` 

From my package.json

New error in style.scss. This wasn't there before but I recopied and pasted from your post and now I'm getting this.

ERROR in ./src/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/lib/loader.js??ref--15-3!./node_modules/postcss-loader/src??postcss!./src/styles.scss)
Module build failed (from ./node_modules/postcss-loader/src/index.js):
Error: Failed to find './custom-tailwind/custom-utilities.css'
  in [
    /workspace/fcc-drum-machine/src
  ]
    at resolveModule.catch.catch (/workspace/fcc-drum-machine/node_modules/postcss-import/lib/resolve-id.js:35:13)

must have been something there. recompiled with an empty custom-utilities.css file
while I'm getting the following waring.

WARNING in ./src/styles.scss (./node_modules/@angular-devkit/build-angular/src/angular-cli-files/plugins/raw-css-loader.js!./node_modules/postcss-loader/src??embedded!./node_modules/sass-loader/lib/loader.js??ref--15-3!./node_modules/postcss-loader/src??postcss!./src/styles.scss)
Module Warning (from ./node_modules/postcss-loader/src/index.js):
Warning

(6:1) /workspace/fcc-drum-machine/src/custom-tailwind/custom-utilities.css is empty

It's compiling now and the grid is now working.

 

🖐
first, thanks a lot for your article!

i'm facing a problem after setting up custom-webpack

i just tried to implement this to an existing project but it seems that it creates error with previous dependencies (like @angular/material or flickity in my case).

Do I have to do something to import/include third party packages?

Example of an error

ERROR in ./src/app/orpheo/orpheo-presentation/orpheo-presentation.component.scss
Module build failed (from ./node_modules/postcss-loader/src/index.js):
ReferenceError: window is not defined
at Object. (C:\Users\Bams\Documents\plvbroker\plvbroker\node_modules\flickity\js\index.js:39:5)
at Module._compile (internal/modules/cjs/loader.js:776:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:690:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object.plugins (C:\Users\Bams\Documents\plvbroker\plvbroker\webpack.config.js:14:23)
at Object.parseOptions (C:\Users\Bams\Documents\plvbroker\plvbroker\node_modules\postcss-loader\src\options.js:18:23)
at Promise.resolve.then (C:\Users\Bams\Documents\plvbroker\plvbroker\node_modules\postcss-loader\src\index.js:51:27)
at process._tickCallback (internal/process/next_tick.js:68:7)

 

// Don't import like this
@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

// Remove this ~
@import '@angular/material/prebuilt-themes/deeppurple-amber.css';

 

Hi Sean, can I use both Angular Material and Tailwind CSS at the same time? I'm worried that it will bloat my project and some CSS utility classes might conflict? Have you tried it before?

I'd like to use Angular Material components and style them with Tailwind CSS. Thanks!

 

I do just that! I use material for things like Modals/Dialogs and Snackbars and Tailwind to style everything.

I don't actually include the Material CSS into my application!

 

This is encouraging but I haven't been able to get Angular/Material and Tailwind to work together with this config. It's possible I'm misunderstanding the build process in Angular 9.

If Tailwind is installed this way before running add for Material it warns you that you are not using the default builder and can't add Material.

If you add Material before tailwind, it borks on @import '~@angular/material/theming'; (which the add command adds for you) in styles.scss with Failed to find '~@angular/material/theming'.

Can you share how you have your projects set up to get them to work together?

Oh I forgot to say. You need to add material first, double check all is working and then add tailwind.

Doing it the other way causes issues with webpack

 

Hi,

Great tutorial on how to implement Tailwind within Angular 9. Thanks for the easy to follow Tutorial. I do come across an issue. I see tailwind being loaded correctly but somehow my components are not getting styled. The styling only goes till root level. Any idea what I'm doing wrong?

Thanks in advance.

Leroy

 

This will only work for the style.scss at root level, the custom web pack doesn't know about the deep level component css files so you can't use the @apply method in component level stylesheets.

In fact, you shouldn't do this as a rule of thumb with Tailwind anyway. Creating your own custom utilities at root level is fine to use everywhere like a .btn class globally, but there is no need for component level utilities, just use the classes in the html. There's a really good video from Adam Watham about the best practices of Tailwind.

youtube.com/watch?v=J_7_mnFSLDg

 

Thanks. This works and I can even use @apply in individual components' .scss files.

 
 

But how to get tailwind classes autocompletion?

 
 
 

With purcecss ?
All clases of tailwindcss are compiled and not remove unsed class

 

You can check this PR: github.com/tailwindcss/setup-examp...
I use Tailwind 1.4.4 and angular 9 and checked it - unused classes will be removed only if you add @fullhuman/postcss-purgecss to webpack.config for production build.