Angular Material provides a comprehensive component library based on Google’s Material Design 3 specification. Setting it up correctly — theme, typography, and dark mode — establishes a consistent visual foundation for the entire BlogApp. Material Design 3’s theming system uses “color roles” (primary, secondary, tertiary, surface, error) that adapt automatically for light and dark modes, eliminating manual dark mode CSS. The correct setup takes 15 minutes and saves hours of custom styling.
Angular Material Theme Configuration
// 1. Install: ng add @angular/material
// ── app.config.ts ─────────────────────────────────────────────────────────
export const appConfig: ApplicationConfig = {
providers: [
provideAnimationsAsync(), // required for Material animations
provideRouter(routes),
provideHttpClient(),
],
};
/* ── styles.scss — Material Design 3 theme ──────────────────────────────── */
@use '@angular/material' as mat;
/* ── Include core styles once ─────────────────────────────────────────────*/
@include mat.core();
/* ── Define the application theme ─────────────────────────────────────────*/
$blogapp-theme: mat.define-theme((
color: (
theme-type: light,
primary: mat.$azure-palette, /* blue-based primary */
tertiary: mat.$violet-palette,
),
typography: (
brand-family: 'Inter, sans-serif',
plain-family: 'Roboto, sans-serif',
),
density: (
scale: 0, /* 0=default, -1=compact, -2=more compact */
),
));
/* ── Apply to html element ─────────────────────────────────────────────── */
html {
@include mat.all-component-themes($blogapp-theme);
height: 100%;
}
body {
margin: 0;
height: 100%;
font-family: var(--mat-sys-body-large-font);
background-color: var(--mat-sys-background);
color: var(--mat-sys-on-background);
}
/* ── Dark mode — automatic via prefers-color-scheme ─────────────────────*/
$blogapp-dark-theme: mat.define-theme((
color: (
theme-type: dark,
primary: mat.$azure-palette,
tertiary: mat.$violet-palette,
),
));
@media (prefers-color-scheme: dark) {
html {
@include mat.all-component-colors($blogapp-dark-theme);
}
}
/* ── Typography scale — use Material type tokens ──────────────────────── */
h1 { font: var(--mat-sys-headline-large); }
h2 { font: var(--mat-sys-headline-medium); }
h3 { font: var(--mat-sys-headline-small); }
p { font: var(--mat-sys-body-large); }
/* ── Utility classes ───────────────────────────────────────────────────── */
.full-width { width: 100%; }
.text-center { text-align: center; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.gap-1 { gap: 0.5rem; }
.gap-2 { gap: 1rem; }
--mat-sys-primary, --mat-sys-surface) throughout all components. These tokens automatically switch between light and dark values based on the theme type. Using these tokens in your custom component styles instead of hardcoded hex colors gives you automatic dark mode support: color: var(--mat-sys-on-surface) renders dark text in light mode and light text in dark mode without any additional CSS.density: { scale: -1 } option to create a compact layout for data-dense admin screens and scale: 0 (default) for comfortable consumer-facing screens. You can also apply density to individual components: @include mat.button-density(-1) in a specific component’s SCSS file creates compact buttons only in that component without affecting the rest of the application.@use '@angular/material' as mat at the top of styles.scss before any other Angular Material usage. The mat.core() mixin must be included exactly once — it registers global styles for Material overlays, ripples, and focus indicators. Including it multiple times creates duplicate CSS. If you use per-component styles (styleUrls), only import the specific component theme mixin there, never mat.all-component-themes() which includes all components and balloons the CSS bundle.Common Mistakes
Mistake 1 — Importing all-component-themes in multiple places (bloated CSS bundle)
❌ Wrong — including mat.all-component-themes() in both styles.scss and component SCSS files; duplicates all Material CSS.
✅ Correct — include mat.all-component-themes() once in styles.scss; use component-specific mixins in component SCSS files if customisation is needed.
Mistake 2 — Hardcoding colors instead of Material tokens (no dark mode support)
❌ Wrong — color: #1976d2 in component CSS; ignores the theme; wrong color in dark mode.
✅ Correct — color: var(--mat-sys-primary); adapts to light/dark theme automatically.