Skip to content

Make Tailwind CSS v4 play nice with Angular Material

In my previous post I walked you through a suggested approach for migrating an Angular project with Sass to Tailwind v4. The outcome of that was to still have Tailwind imported, configured, and customised within the Sass file (styles.scss), which is not ideal as Tailwind is not designed to be used with preprocessors like Sass, and you may encounter various issues when using Tailwind (and it’s capabilities) in a .scss file.

So, instead, the goal is to play on each tool’s strengths and have them integrated together in a way that works.

In this post, I’ll show you how to separate the Tailwind CSS and SCSS processing out in to separate files, but integrated together, so you can have both Tailwind v4 and Angular Material co-exist and play nice together.

You can see a real-world example of this refactor in my Angular and Firebase template:

https://github.com/FullStacksDev/angular-and-firebase-template/pull/27

  • We put all Tailwind specific imports, configuration, styles, overrides, and customisations in a new src/tailwind.css file.
    • Here, we’ve set up the Tailwind utilities to be marked as !important, to take highest precedence (more on this below).
  • We keep the src/styles.scss file as the entrypoint for all outputted CSS, and the one that Angular links to as the stylesheet for the app.
    • This is where we set up and customise Angular Material.
    • This is also where we import our src/tailwind.css file, which Sass treats as a regular CSS import.
    • We also provide styling overrides to make Angular Material work well with the Tailwind CSS base styles.

Here is an example of the src/tailwind.css file we’ve created:

src/tailwind.css
@layer theme, base, components, utilities;
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css" layer(utilities) important;
@layer base {
/*
The default border color has changed to `currentColor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
}

We could’ve simply had @import "tailwindcss"; but we want more control, mainly to configure the utilities as !important. We want these to take highest precedence in our app, to allow overriding of all other styling (as that’s usually the purpose of using utility classes). In particular, so they can be used to override Angular Material component styles, when needed. Example:

<button mat-button class="bg-blue-500 text-white">Click me</button>

Here is an example of the contents of the src/styles.scss file:

src/styles.scss
// Custom Theming for Angular Material
// For more information: https://material.angular.io/guide/theming
@use "@angular/material" as mat;
@import "./tailwind.css"; // This is importing our local Tailwind CSS file
@layer base {
html {
background: var(--mat-sys-surface);
color: var(--mat-sys-on-surface);
@include mat.theme(
(
color: (
theme-type: light,
primary: mat.$azure-palette,
tertiary: mat.$blue-palette,
),
typography: Roboto,
density: 0,
),
$overrides: (
// Custom background and foreground colors
surface: var(--color-slate-50),
on-surface: var(--color-slate-900)
)
);
}
html,
body {
height: 100%;
margin: 0;
}
body {
font-family: Roboto, "Helvetica Neue", sans-serif;
margin: 0;
}
// ----------------------------------
// Make Angular Material and Tailwind play nice
.mat-mdc-form-field.mat-mdc-form-field.mat-mdc-form-field.mat-mdc-form-field.mat-mdc-form-field
.mdc-notched-outline__notch {
border-right-style: hidden;
}
[type="text"],
[type="email"],
[type="url"],
[type="password"],
[type="number"],
[type="date"],
[type="datetime-local"],
[type="month"],
[type="search"],
[type="tel"],
[type="time"],
[type="week"],
[multiple],
textarea,
select {
padding: 0;
border: none;
}
// ----------------------------------
}

You can see here how we import our src/tailwind.css file, and then set up and customise Angular Material. We also provide some styling overrides to make Angular Material work well with the Tailwind CSS base styles.

We’ve wrapped all of the declarations in @layer base so they are placed in the 'base' CSS cascade layer, to give us some control over the cascade order. Though note that the styles for Angular Material components are not emitted here, but in the <head> of the page (see the “Info” box, above).

Typically, you’ll want to put your custom global classes and styles in the tailwind.css file as you’ll likely want to use Tailwind capabilities (like @apply) to build up your styles. Note that you can still refer to Angular Material’s CSS variables here.

However, anything that needs Sass processing, or is specific to Angular Material, should be placed in the styles.scss file.