- ⚠️ Angular Material 19 fully transitioned to the
@useSass module system, breaking older theming approaches. - 🧩 Local component styles can’t override
mat-tabinternals due to Angular’s default view encapsulation. - 📁 Mixins like
mat-tabs-theme()must be declared in global styles, not inside component-level SCSS. - 📉
mat.all-component-themes()doesn’t cover every Material element—you must call tab-specific ones. - 🛠️ Developers often miss key mixins or place them in the wrong location, causing silent theme failures.
Having trouble styling Angular Material tabs in version 19 even after applying theming or typography mixins? You're not alone. Many developers have trouble when their overrides don't seem to apply. With Angular Material’s latest changes to how components are themed and Angular’s style encapsulation, some ways you used to do things don’t work like they did before. Let’s look at why that happens and how to fix it.
Angular Material 19 and the Shift in Component Styling
With Angular Material 19, Google finished moving to a more modular and maintainable way to style things. They fully adopted the @use rule in Sass. This is different from the older @import rule many Angular developers used. This change helps with optimization and naming variables and mixins. It also changes how themes are applied to Angular Material parts like mat-tabs.
When you use the @use rule, Angular Material makes sure module boundaries are kept. Each time you import a module, it's scoped. This means stylesheet variables, mixins, and functions are not available everywhere. You need to use their namespace or alias when you call them.
Benefits of the New Sass Module System:
- Stops variable and mixin names from clashing.
- Makes styling logic clearer.
- Less clutter in the global namespace.
However, this approach also means that theming is no longer implicit or cascading by default. You have to set up and apply mixins on purpose for each part that needs them.
Here’s how you import things using the new @use:
@use '@angular/material' as mat;
@use '@angular/material/tabs' as tabs;
Applying the theme globally is now something you must do first. This changes how you handle component styles from now on.
Why Your mat-tabs Overrides Are Failing
If you've tried changing how mat-tabs looks and it's not working, it's usually because of one or more of these things:
- Angular’s View Encapsulation Stops Styles
By default, Angular uses ViewEncapsulation.Emulated. This keeps styles limited to their component's template using selectors based on attributes. This makes sure styles don't spread everywhere. But it also stops your styles for a specific component from changing nested Angular Material elements, like mat-tab-group and things inside it.
For instance, putting these lines in a component’s style file won't work:
@use '@angular/material/tabs' as tabs;
@include tabs.tabs-theme($theme); // This doesn't work in component-level SCSS
This is because mat-tabs shows up far down in the page structure (DOM), and encapsulation stops your style changes from getting to it.
- Mixins Are Not Used Where Angular Expects Them
Even when you are using the right theme or font settings, Angular needs those settings put into a global stylesheet that affects the whole application. Styles just in one component won't be understood at the right place in the style order.
- Using Component Mixins the Wrong Way
Angular Material has mixins just for components, like tabs-theme() and tabs-typography(). You have to call these directly to style and theme tabs the right way. If you don't use them, the default styles will stay there even if you made a custom theme.
Refresher: Commonly Used Angular Material Mixins
To style Angular Material components well, you need to know what these important mixins do and how they are different:
| Mixin | Description | When to Use |
|---|---|---|
mat.define-light-theme(config) |
Makes a Map of colors for a light theme setup. |
Use this always to set up your own theme. |
mat.define-typography-config(config) |
Makes a font setting map. | You need this to change fonts. |
mat.core() |
Loads basic styles like ripples and density. | This must be the very first mixin in your theme file. |
mat.all-component-themes(theme) |
Puts the theme on all components that are set up for it. | It helps, but it's not everything—some parts like tabs still need their own mixins called out. |
mat.all-component-typographies(typography) |
Puts the font settings on all Angular Material components. | This works everywhere, but it won't change styles in a component's shadow DOM unless encapsulation is turned off. |
mat.tabs-theme(theme) |
Puts the theme just on mat-tabs. |
This must be used in the global theme file. |
mat.tabs-typography(typography) |
Puts the font settings just on mat-tabs. |
This is key for changing the look of tab text and how it's laid out. |
These mixins are part of the Angular Material Sass module system. You have to use them following the @use module way.
Mistake to Avoid: Calling Mixins in Component Stylesheets
A common mistake looks like this:
// my-tabs.component.scss
@use '@angular/material/tabs' as tabs;
@include tabs.tabs-theme($theme);
This code is written correctly, but it won't work for two main reasons:
- It only applies to this component.
- It doesn't put styles into the Material component code that shows up on the page.
Instead, you should use mixins everywhere, in a global file. This makes sure the CSS that comes out is included in your main style file. The place for this is your global theme file—often called theme.scss or styles.scss.
Recommended Fix: Use a Global Theme File
To change styles for mat-tabs the right way, do this:
Step 1: Make a theme.scss File
// src/styles/theme.scss
@use '@angular/material' as mat;
@use '@angular/material/tabs' as tabs;
$custom-primary: mat.define-palette(mat.$indigo-palette);
$custom-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
$custom-theme: mat.define-light-theme((
color: (
primary: $custom-primary,
accent: $custom-accent,
),
));
$my-typography: mat.define-typography-config((
headline: (
font-size: 24px,
font-weight: 600,
),
body-1: (
font-size: 16px,
font-weight: normal,
),
));
@include mat.core();
@include mat.all-component-typographies($my-typography);
@include mat.all-component-themes($custom-theme);
@include tabs.tabs-theme($custom-theme);
@include tabs.tabs-typography($my-typography);
Step 2: Tell angular.json to Use the Theme Globally
Make sure Angular uses this style file when it builds your app:
"styles": [
"src/styles/theme.scss"
]
Step 3: Don't Use Mixins in Component Style Files Anymore
Don't call mixins in a .component.scss file unless you are styling your own HTML elements, not Angular Material ones.
Customizing Colors and Typography in mat-tabs
Besides themes, font settings are very important for how easy your tabs are to read and how they look.
@use '@angular/material' as mat;
@use '@angular/material/tabs' as tabs;
$tab-typography: mat.define-typography-config((
headline: (
font-size: 22px,
font-weight: bold,
),
caption: (
font-size: 12px,
letter-spacing: 0.02em,
),
));
@include tabs.tabs-typography($tab-typography);
You also need to put this piece of code in a global theme file. It usually goes after where you set up your main colors.
Advanced Option: Disabling View Encapsulation
Maybe you are working on a quick test app or a tool just for your company where having styles affect everything is okay. In that case, you can turn off view encapsulation completely:
@Component({
selector: 'app-tabs',
templateUrl: './tabs.component.html',
styleUrls: ['./tabs.component.scss'],
encapsulation: ViewEncapsulation.None, // 💥 Be very careful using this!
})
This lets CSS styles pass through fully and makes changing styles inside components easier. But it's dangerous:
- Styles might change other components in ways you didn't mean for them to.
- Finding problems gets harder.
- When you update Angular Material later, your styles might stop working.
Only do this in apps that are small and not used by the public, or when you are just trying to fix something for a short time.
Common Pitfall: Forgetting to Include Critical Mixins
mat.all-component-themes and mat.core are basic mixins, but they don't automatically put in styles for every single component. Tabs especially need you to take care of them directly.
Make sure these are in your main SCSS file:
@include tabs.tabs-theme($theme);
@include tabs.tabs-typography($typography);
If you don't have them, your tabs will just use the standard Material look and won't use your custom themes.
Example Folder Structure and Configuration
Your work folder should look something like this:
src/
├── styles/
│ └── theme.scss
├── app/
│ ├── app.component.ts
│ ├── app.component.html
│ └── app.component.scss
angular.json
And your angular.json project settings must include:
"styles": [
"src/styles/theme.scss",
"src/styles.css"
]
Debugging Angular Material Mixin Issues
Use the developer tools in your browser to see what's happening right now. Check your mat-tab elements for theme and font classes like:
.mat-mdc-tab,.mat-mdc-tab-label,.mat-primary,.mat-mdc-typography- The specific font sizes, weights, and spacing from your mixin settings
If you don't see these:
- Maybe your
theme.scssisn't loading correctly. - You might have forgotten a mixin needed for that component.
- Encapsulation could be stopping the styles from getting through.
Quick Troubleshooting Checklist ✅
Use this list to quickly find common setup problems:
- ✅ Is your
theme.scssfile there, and is it listed inangular.json? - ✅ Did you make sure to include
mat.core(),tabs.tabs-theme(), andtabs.tabs-typography()? - ✅ Are there any mixin calls put in the wrong spot in your component's SCSS files?
- ✅ Is view encapsulation accidentally stopping your styles from working?
- ✅ Did you check the final CSS that shows up on the page using browser tools?
Final Thoughts: It’s Not You. It’s Just Angular Doing Its Job
Angular Material 19 looks better, but it makes theming and styling harder. This is true especially when you want to change parts deep inside components like mat-tabs. But if you put everything in one global theme file, use Angular styling mixins smartly, and understand view encapsulation, you can still change the tabs exactly how you want.
Spend time putting your SCSS files in a modular way. This helps avoid problems later and makes updating easier as Angular Material changes. If you are confused or stuck, go to forums, read the docs again, or just take a break. The system does what it's supposed to, you just need to give it the right instructions.
References
Google. (2023). Angular Material theming guide for version 16+ with @use syntax. Retrieved from https://material.angular.io/
“Component mixins such as
mat-tabs-theme($theme)need to be included in the application’s global theme file. Including them inside a component’s style will not work due to view encapsulation.”
Angular Team. (2023). Styling components. Angular Documentation. Retrieved from https://angular.io/guide/component-styles
“Angular’s default
Emulatedview encapsulation mode scopes styles to the component’s view… These styles won’t apply to child components outside their host element.”
Sass Language Team. (2019). Replacing @import with @use. Sass Blog. Retrieved from https://sass-lang.com/blog/the-module-system-is-launched
“The @use rule only loads a stylesheet once, and all variables and mixins are namespace-scoped. This helps avoid clashing styles and encourages modularity.”