TL;DR: This configuration is tested on Angular 9. It is also working on the previous version of Angular such as 8.x.x. It is also working with AOT when you do ng build --aot=true
My friend @nartc Just released an @angular schematics to add @tailwindcss
to your @angular/cli projects.
purge
for TS and HTML filesangular.json
and styles.scss
Simply run a single command on your Angular CLI project, and you are all set!
ng add @ngneat/tailwind
See more ⥠https://github.com/ngneat/tailwind
Everyone has a different way of organizing and working with CSS. I always encounter some use case where I need to set a simple padding-left: 5px
, or margin: 0 auto
, or to make an element to have cursor: pointer
.
I have a few options for doing so.
<button style="padding-left: 5px;">Submit</button>
<i style="cursor: pointer;"></i>
<button class="my-button">Submit</button> <i class="fa fa-help my-icon"></i>
And write a corresponding CSS for them.
.my-button {
padding-left: 5px;
}
.my-icon {
cursor: pointer;
}
Because Angular has encapsulated the stylesheet, it will ensure that these classes will be available only in the component itself. I donât have to worry about polluted the global CSS.
Suppose you see they are repeating again and again on a different component. In that case, I could also bring all of that classes into app.component.scss
and set the ViewEncapsulation.None
to use in all the other components. But, the class name has to be changed because Those classes will be reused in many places.
.pl-1 {
padding-left: 5px;
}
.icon-active {
cursor: pointer;
}
If I need a padding-left: 10px
, I can just add new class .pl-2 { padding-left: 10px }
to app.component.scss
. In real life I will use SCSS loop to generate them, but let assume I do it manually for now.
It is convenience, but many problems arise with this approach
Thatâs when you come to use TailwindCSS. I have been using it quite sometimes, and it is amazing.
TailwindCSS is a highly customizable, low-level CSS framework that gives you all of the building blocks you need to build bespoke designs without any annoying opinionated styles you have to fight to override.
In short, TailwindCSS create all the utility class for you. What you need to do is to spend about half an hour trying TailwindCSS, know some standard classes and syntax. You are good to go.
If youâre reading this and you donât know what TailwindCSS is, where have you been?
â ď¸ The below manual approach has several issues recently due to incompatible with the new breaking changes from postcss
and @angular-builders/custom-webpack
. Proceed with our own risk đ
Some known issues that I have received from people.
Schema validation failed with the following errors:
Data path "" should NOT have additional properties(customWebpackConfig).
We can fix it by remove the customWebpackConfig
from the builder for serve.
But after doing it, we faced another issue below, which I was looking for online. People only mentioned about the mismatched version of CLI and TypeScript and the like. I have no idea how to solve it. If you find the solution, please leave your comment đ¤Ł
An unhandled exception occurred: Cannot read property 'flags' of undefined
So I highly recommend you use ngneat/tailwind that I mentioned above for installing TailwindCSS into your Angular application.
If you are not using CLI and have your own webpack configuration. It is still applicable, though
I have prepared a simple application while writing this blog post. View the source code.
Suppose you have already had an Angular application create with Angular CLI. Follow those below steps.
On Windows, simple type cd path/to/your/folder
.
npm i tailwindcss postcss-scss postcss-import postcss-loader @angular-builders/custom-webpack -D
We will need @angular-builders/custom-webpack
for customizing the build process of Angular CLI by overriding some of the webpack configurations.
Next, you need to add the following to the top of the /src/style.scss
.
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
postcss-loader@^3.0
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
loader: 'postcss-loader',
options: {
ident: 'postcss',
syntax: 'postcss-scss',
plugins: () => [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
],
},
},
],
},
}
postcss-loader@^4.0
, take this config insteadNoted there is additional postcssOptions
property inside options. See the detail from its documentation
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
loader: 'postcss-loader',
options: {
postcssOptions: {
ident: 'postcss',
syntax: 'postcss-scss',
plugins: ['postcss-import', 'tailwindcss', 'autoprefixer'],
},
},
},
],
},
}
I have some notes on
Tailwind bundle size
andpostcss-scss
for you
When using the default configuration, Tailwind CSSâs development build is 1996kb uncompressed, 144.6kb minified and compressed with Gzip, and 37.kb when compressed with Brotli.
When building for production, you should always use Tailwindâs purge option to tree-shake unused styles and optimize your final build size. When removing unused styles with Tailwind, itâs tough to end up with more than 10kb of compressed CSS.
To enable purge, simply add this option in your tailwind.config.js
// tailwind.config.js
module.exports = {
purge: {
enabled: true,
content: ['./src/**/*.html', './src/**/*.ts'],
},
// ...
}
For more on that, view Tailwind documentation.
It will not compile SCSS. It simply parses mixins as custom at-rules & variables
as properties so that PostCSS plugins can then transform SCSS source code alongside CSS. Mixin and for loop wonât be transformed. You have to use sass-loader
or less-loader
if you need to compile your SASS/LESS code into CSS, then do the postcss-loader
on top of that.
See my webpack.config.js for project jira-clone-angular that use additional sass-loader
But you might ask, what is different between SCSS and PostCSS?
PostCSS is the closest thing in the CSS world to what âBabelâ is in the JavaScript world - it parses CSS, loads plugins that apply transformations to your code, and manages these transformations. SCSS is a preprocessor and can be loaded by PostCSS, but PostCSS can load a lot more than just SCSS :D With PostCSS you could manage SCSS and Less and Stylus code, plus other things - all in the same codebase together.
I still didnât really get what is PostCSS đ In short, To make SCSS/LESS work with PostCSS, please config your webpack.config.js
with an additionally needed loader I mentioned above.
{
"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"
}
}
}
}
}
Important, see the "builder"
has been changed from @angular-devkit/build-angular:dev-server
to @angular-builders/custom-webpack:browser
.
Run npm start
and start adding some Tailwind classes to see if it is working.
Tailwind is great. But with hundreds of utility classes might not be easy to remember. We can configure VSCode to give us all the suggestions for Tailwind.
To do so, follow these steps.
https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss
Simple run npx tailwind init
. It will give you a default configuration file tailwind.config.js
. This extension required this file to be able to work properly.
Thatâs all. You can now use the power of VSCode together with Tailwind, how sweet it is!
Tailwind provides a handy @apply
keyword. Think about If you have ten similar buttons on a sample page. You have to copy the HTML code ten times.
<button
class="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded"
>
Submit
</button>
If you need to change the color, you also have to change 10 times, which is a nightmare.
With @apply
, you can create a new class .btn
and put all the style you want to reuse. Tailwind will transform our code below.
<button class="btn-tailwind">
Submit
</button>
.btn-tailwind {
@apply bg-transparent text-blue-700 font-semibold py-2 px-4 border border-blue-500 rounded;
&:hover {
@apply bg-blue-500 text-white border-transparent;
}
}
The output looks the same as we use classes. For more information on @apply
.
The Intellisense doesnât like the SCSS syntax. It gave the red error underline of the class after using @apply
. But the build work perfectly fine. You should not worry about that. See more about that:
https://github.com/trungvose/angular-tailwind-css-configuration
"@angular/core": "~9.1.11"
. It is working with the previous version of Angular such as 8.x.x
as well.ng build --aot=true
.purge
on tailwind.config.js
for production build.A comprehensive guide of how to configure TailwindCSS - @Sean Kerwin.