Setting up Angular 4 with TailwindCSS

Can TailwindCSS be configured with Angular (4+)?

I am willing to eject the Angular project in order to make webpack configuration accessible. However, I am uncertain about what needs to be included in the webpack.config.js file to ensure that TailwindCSS integrates smoothly with Angular's internals.

It would be ideal to have a setup that allows me to use a single command for development (such as npm start) and continue to have changes in files watched, including CSS. The same convenience should apply when building the project.

Answer №1

Option 1: (using ng-eject)

If you're looking to integrate Sass and TailwindCSS into your Angular project, follow the steps outlined in this informative video by Tom Gobich:

  1. Begin by incorporating Sass into your project with the command:

    $ ng new project --style=scss
    
  2. Next, install tailwindcss and generate the config file:

    $ cd project
    $ npm install tailwindcss --save-dev 
    $ ./node_modules/.bin/tailwind init tailwind.config.js
    
  3. Eject your app to output the webpack configuration file and resolve new dependencies:

    $ ng eject
    $ npm install
    
  4. Add the tailwindcss plugin to your webpack.config.js file:

    const tailwindcss = require('tailwindcss');
    ...
    
    const postcssPlugins = function () {
       ...
       return [
          postcssUrl({
            ...
          }),
          tailwindcss('./tailwind.config.js'),
          autoprefixer(),
          ...
     };
    
  5. Include the @tailwind directives in your src/styles.scss file:

    @tailwind preflight;
    
    // custom components here.
    
    @tailwind utilities;
    
    // custom utilities here.
    
  6. Create your tailwind components or import sample code into src/app/app.component.html for testing purposes, then run:

    $ npm start
    

Option 2: (without ng-eject)

If you prefer not to use ng-eject, you can refer to this helpful article by @hackafro (Richard Umoffia) on utilizing Tailwind's CLI to process your stylesheet:

$ ng new project
$ cd project
$ npm install tailwindcss --save-dev 
$ ./node_modules/.bin/tailwind init tailwind.config.js

Create a new file called tailwind-build.css at the same level as styles.css, and include the following content:

@tailwind preflight;

// custom components here.

@tailwind utilities;

// custom utilities here.

In your package.json file, add these scripts under the script attribute:

{
  ...
  "scripts": {
    ...
    "tailwind": "./node_modules/.bin/tailwind build ./src/tailwind-build.css -c ./tailwind.config.js -o ./src/styles.css",
    "prestart": "npm run tailwind"
  }
},

By running npm run tailwind whenever you start your server, Tailwind's CLI will populate the content of ./src/styles.css efficiently, thanks to angular-cli applying postCSS plugins like autoprefixer. Learn more about this process here.

Answer №2

Utilizing chokidar with JavaScript, I created a solution to automatically build my tailwind files whenever changes are made since Angular (up to version 6.0.3) does not currently provide access to postcss plugins in CLI projects.

Here is the snippet from chokidar.js located at the top-level next to package.json:

const chokidar = require('chokidar')
const child = require('child_process')

const tailwind = chokidar.watch(['tailwind.js', './src/tailwind.css'])

tailwind.on('change', (event, path) => {
  child.exec('npm run build-tailwind')
  console.log('Reprocessing Tailwind Files')
})

Snippet from package.json scripts:

"scripts": {
  "ng": "ng",
  "build-tailwind": "./node_modules/.bin/tailwind build ./src/tailwind.css -c ./tailwind.js -o ./src/styles.css",
  "prestart": "npm run build-tailwind",
  "start": "ng serve & node chokidar.js",
  "build": "npm run prestart && ng build"
}

In the build-tailwind script, I placed tailwind.css in the src/ folder alongside styles.css for all custom CSS implementations within the tailwind project setup.

The contents of tailwind.css:

@tailwind preflight;

/* custom components */

@tailwind utilities;

/* custom utilities */

This workaround can be beneficial until Angular integrates direct support for post-css functionality.

UPDATE:

To simplify this process for others looking to leverage tailwind capabilities in Angular projects, I developed a CLI tool available on npm:

https://www.npmjs.com/package/ng-tailwindcss

Answer №3

If you're looking for a more efficient method that doesn't involve ejecting the CLI or creating a specific npm script for tailwind, you can simply tap into your CLI's webpack loaders.

Start by installing

npm install -D @angular-builders/custom-webpack postcss-scss tailwindcss

Next, set up a custom configuration file named webpack.config.js:

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

Update your angular.json file to utilize this new configuration:

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

Include the tailwind utilities in your styles.scss

@tailwind base;
@tailwind components;
@tailwind utilities;

Finally, just run npm start and you'll be all set to use tailwind classes in your HTML or apply them in your SCSS files!

For a more detailed explanation, check out my blog post - https://medium.com/@joao.a.edmundo/angular-cli-tailwindcss-purgecss-2853ef422c02

Answer №4

For those who encounter the issue of receiving the error message "atRule.before is not a function" after following Salem's solution, simply ensure all PostCSS dependencies are up to date with the latest version for seamless functionality.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

jQuery is optimized to work specifically with select id tags

Here is the HTML code snippet I've put together, along with my script. While I admit it might look a bit messy, please bear with me as I'm still in the learning phase. If anyone could offer some assistance on this matter, I would be extremely gra ...

How can I customize the styling of an SVG pseudo element using Font Awesome 5?

I've implemented font awesome 5 pseudo elements to attach an :after tag to my element as shown below: &:after { content: "\f068"; font-weight:400; color:$brandRed; float:right; font-family: "Font Awesome 5 Pro"; } The c ...

The arrangement of bootstrap elements varies based on whether they are displayed in one or two columns

I'm facing a challenge with my webpage layout that displays two columns of cards. When the screen width is smaller than md size, I want the most important items to be positioned higher on the page. To achieve this, I have arranged the items alphabetic ...

Ensure that the text is contained within a div element with a border-radius of 100%

Is there a way to set text inside a div with a border-radius of 100% in a circular shape? I have paragraphs and ul li's within the div, but the text goes outside the borders. How can I wrap the text within the curved edges of the div? ...

Eliminate Angular Firebase Object and Storage

Currently in the final stages of completing my initial project using Angular and Firebase. I have encountered a query regarding the deletion of objects utilizing both technologies. My service is designed to delete an object that contains a nested object n ...

Problem with IE off-canvas scrolling

Currently, I am facing an issue with the scrolling functionality of an off-canvas sidebar on my Joomla 3 website. It seems to be working fine in Chrome and Firefox, but when it comes to Internet Explorer, the visible scroll bar refuses to move when attempt ...

Issue with alignment of Bootstrap inline form field on top and bottom levels

I seem to be encountering an issue highlighted in the image below: My goal is to have the state dropdown perfectly aligned with the top and bottom edges of the other two controls. Here's the code snippet I've used to create this section of the i ...

Tips for marking a p-checkbox as selected and saving the chosen item to a list

Here is a sample list: rows: any[] = [ {"id":"1721079361", "type":"0002", "number":"2100074912","checked":true}, {"id":"1721079365", "type":"0003", "number":"2100074913","checked":false}, {"id":"1721079364", "type":"0004", "number":"2100074914"," ...

Learn how to navigate through the extensive file structure in Eclipse's Project Explorer after compiling the Angular 2 tutorial 'Tour of Heroes'

I am currently in the process of learning AngularJS 2 using the 'Tour of Heroes' tutorial with Typescript. Everything has been going well so far, but I have noticed something peculiar while working on this tutorial. After compiling with NodeJs, a ...

Turning off and on CSS transitions to set the initial position

Is there a way in javascript to position divs with rotations without using transitions initially for an animation that will be triggered later by css transition? I have tried a codepen example which unfortunately does not work on the platform but works fin ...

Fixed table layout prevents table cells from expanding inside a 100% width table row with absolute positioning, while also ensuring that the elements do not collapse

I'm struggling to understand this, as I am not very well-versed in CSS. I would consider myself more of a beginner than an expert. The reason why I am using relative/absolute is because I am working with dynamically paginated tables from large datase ...

Process for generating Firebase users using Cloud Function

As I develop my Angular app with a Google Firebase backend, I encounter a many-to-many relationship between "users" and "clubs." Here's how it looks: User Club First Name Name Last Name Member Count Phone Number Collection of Documents wit ...

Button with small width containing an icon and text

I am trying to create a simple HTML button that has an icon on top and a description below it. <div class="mybtn"> <div><img src="someimage.png"></div> <div>Button description</div> </div> My question is, ...

utilizing a background image with a specific div identifier

I am attempting to achieve the same effect shown in this example: http://www.w3schools.com/cssref/tryit.asp?filename=trycss_background-position I want to set an image as the background of a div using an id. #wrapper { height: 900px; width: 900px; bord ...

Utilize specific CSS attributes from a class and apply them to a DOM element

It's clear that the question at hand is more complex than it initially appears. I'm not just looking for a way to apply a CSS class to a DOM element, as I'm already familiar with that (<div class="MyCssCLass"></div>) My goal is ...

Bootstrap navigation bar unresponsive on mobile devices

<nav class="navbar navbar-expand-sm fixed-top navbar-dark bg-dark"> <a class="navbar-brand" href="#">Yehee-Lounge</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#nav ...

Updating the Animation for Datepicker Closure

While using the date picker, I want it to match the width of the input text box. When closing the date picker, I prefer a smooth and single motion. However, after selecting a from and to date, the datepicker no longer closes smoothly. I have attempted sol ...

When initially compiling Angular 5, an error (TS2339) may occur, but after a successful compilation, everything runs smoothly

In a unique scenario, I wrote code that fetches information from an API server without knowing the structure of the response fields. Once I receive the response, I need to create a form for updating the data and sending it back. To handle unknown ngModel p ...

React component for a background image with a gradient overlay

I'm facing an issue trying to incorporate a background image for a div along with a color overlay. In plain CSS, the code would typically look like this: .backgroundImage { background-image: linear-gradient(to bottom, rgba(245, 246, 252, 0.52), rg ...

Error occurs when attempting to filter data through input text pasting in Angular

Currently, I am working on a web application that utilizes the Angular framework and angularfire2. The issue I am encountering is related to the data filter functionality not functioning correctly when pasting copied text. Interestingly, it works perfectly ...