MatToolbar Color Issue in Angular Material v18
Problem Statement
Angular Material v18 introduced changes that cause the color
input on the MatToolbar
component to stop working. While other components like mat-button
and mat-icon
still respond to the color
attribute, the toolbar remains unstyled. The toolbar appears with minimal visibility against a white background instead of displaying the expected theme color (e.g., Material's Rose/Red theme).
Key observations:
color="primary"
works for buttons and icons but not toolbars- Manually setting
background-color
in CSS works as expected - Creates inconsistent UI when toolbar ignores theme colors while other components respect them
<!-- This works -->
<button mat-button color="primary">Button</button>
<!-- This also works -->
<mat-icon color="primary">home</mat-icon>
<!-- This DOESN'T work -->
<mat-toolbar color="primary">Toolbar Space</mat-toolbar>
Cause
This issue stems from Angular Material's migration from Material Design 2 (M2) to Material Design 3 (M3). The color
input was an M2 feature. In M3 (v18+), the toolbar uses new CSS variable tokens instead of the legacy color system.
Compatibility Notice
Material v18 provides backward compatibility for components like buttons and icons, but toolbars aren't included in this compatibility layer by default.
Solutions
Solution 1: Enable M2 Backward Compatibility
Add M2 backward compatibility to your global styles (recommended for existing projects migrating to v18):
- In
styles.scss
/styles.css
:
@use '@angular/material' as mat;
$theme: mat.define-theme(); // Use your existing theme configuration
html {
@include mat.all-component-themes($theme);
@include mat.color-variants-backwards-compatibility($theme); // ← Key addition
}
- Restart your development server
Limitation
This solution restores M2 behavior but may limit access to new M3 features in toolbars.
Solution 2: Use Material 3 Theming (Recommended)
For new projects or those adopting M3 fully, use token-based styling:
- In your global styles file:
@use '@angular/material' as mat;
:root {
@include mat.toolbar-overrides((
container-background-color: var(--mat-sys-primary-container),
container-text-color: var(--mat-sys-primary),
));
}
- Customize per component if needed:
// component.scss
.my-custom-toolbar {
@include mat.toolbar-overrides((
container-background-color: var(--mat-custom-color),
container-text-color: white,
));
}
<mat-toolbar class="my-custom-toolbar">...</mat-toolbar>
Component-Specific Style (for icons/buttons in toolbar)
.toolbar-icon {
color: var(--mat-sys-primary);
}
Solution 3: Direct CSS Variable Manipulation
For quick fixes without theming system:
mat-toolbar {
$primary: #f8a5c2; // Rose primary color
--mat-toolbar-container-background-color: #{$primary};
--mat-toolbar-container-text-color: rgba(0, 0, 0, 0.87);
}
Solution 4: Theme-Based Variable Setting
For multi-theme applications:
@use '@angular/material' as mat;
$light-theme: mat.define-theme((
color: (theme-type: light, primary: mat.$rose-palette)
));
$dark-theme: mat.define-theme((
color: (theme-type: dark, primary: mat.$red-palette)
));
:root {
--mat-toolbar-container-background-color: #{mat.get-theme-color($light-theme, primary, 80)};
}
.dark-theme {
--mat-toolbar-container-background-color: #{mat.get-theme-color($dark-theme, primary, 30)};
}
Key Concept Explanation
Angular Material 3 introduced design token variables instead of fixed color mappings. The tokens are:
Token Variable | Purpose | Example Value |
---|---|---|
--mat-sys-primary | Primary text color | #c2185b |
--mat-sys-primary-container | Primary background color | #f8a5c2 |
--mat-toolbar-container-background-color | Toolbar-specific background | Inherits from system |
Why Toolbars Behave Differently
Toolbars use container
tokens instead of direct palette mapping. This allows for finer control over "surface" vs "container" elements in Material 3's updated design philosophy.
Best Practices
- Prefer M3 tokens for new projects (
--mat-sys-*
) - Check component-specific tokens using browser DevTools
- Audit theme compatibility when upgrading
- Use theme mixing for maintainability:
@mixin toolbar-theme($theme) {
mat-toolbar {
--mat-toolbar-container-background-color: mat.get-theme-color($theme, primary-container);
}
}