Skip to main content

Angular Material 2 Theming Guide for Modern Angular

Using M2 (Legacy) Theming in Latest Angular Versions

This guide demonstrates how to configure and use Material 2 theming in the latest Angular versions with a custom purple color palette.


1. Color Palette Definition

// Custom Purple Theme
$custom-purple: (
50: #f3e5f5,
100: #e1bee7,
200: #ce93d8,
300: #ba68c8,
400: #ab47bc,
500: #9c27b0,
600: #8e24aa,
700: #7b1fa2,
800: #6a1b9a,
900: #4a148c,
A100: #ea80fc,
A200: #e040fb,
A400: #d500f9,
A700: #aa00ff,
contrast: (
50: rgba(black, 0.87),
100: rgba(black, 0.87),
200: rgba(black, 0.87),
300: rgba(black, 0.87),
400: rgba(white, 0.87),
500: rgba(white, 0.87),
600: rgba(white, 0.87),
700: rgba(white, 0.87),
800: rgba(white, 0.87),
900: rgba(white, 0.87),
A100: rgba(black, 0.87),
A200: rgba(white, 0.87),
A400: rgba(white, 0.87),
A700: rgba(white, 0.87),
),
);

// Complementary accent color (lime green)
$custom-accent: (
50: #f9fbe7,
100: #f0f4c3,
200: #e6ee9c,
300: #dce775,
400: #d4e157,
500: #cddc39,
600: #c0ca33,
700: #afb42b,
800: #9e9d24,
900: #827717,
A100: #f4ff81,
A200: #eeff41,
A400: #c6ff00,
A700: #aeea00,
contrast: (
50: rgba(black, 0.87),
100: rgba(black, 0.87),
200: rgba(black, 0.87),
300: rgba(black, 0.87),
400: rgba(black, 0.87),
500: rgba(black, 0.87),
600: rgba(black, 0.87),
700: rgba(black, 0.87),
800: rgba(white, 0.87),
900: rgba(white, 0.87),
A100: rgba(black, 0.87),
A200: rgba(black, 0.87),
A400: rgba(black, 0.87),
A700: rgba(black, 0.87),
),
);

2. Theme Configuration

@use '@angular/material' as mat;

// Import fonts and custom typography
@import './assets/fonts/yourfonts.scss';
@import './_custom-typography.scss';

/*
// Define typography configuration
$custom-typography: mat.m2-define-typography-config(
$font-family: 'Your Font, sans-serif'
);
*/

// Include Material core styles
@include mat.core();
@include mat.typography-hierarchy($custom-typography);
@include mat.all-component-typographies($custom-typography);

// Define the palettes with M2 compatibility functions
$primary-palette: mat.m2-define-palette($custom-purple);
$accent-palette: mat.m2-define-palette($custom-accent);
$warn-palette: mat.m2-define-palette(mat.$red-palette);

// Create the theme
$custom-theme: mat.m2-define-light-theme($primary-palette, $accent-palette, $warn-palette);

// Include theme styles for all components
@include mat.all-component-themes($custom-theme);

// Create aliases to use within your app
$my-app-palette-primary: $primary-palette;
$my-app-palette-accent: $accent-palette;
$my-app-palette-warn: $warn-palette;

3. Custom Typography

// Import standard web fonts if needed
// @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap');

// Font family variables
$header-font-family: 'Helvetica Neue', Arial, sans-serif;
$body-font-family: 'Source Sans Pro', 'Open Sans', Arial, sans-serif;

// Base font sizes
$font-size-xs: 12px;
$font-size-sm: 14px;
$font-size-md: 16px;
$font-size-lg: 18px;
$font-size-xl: 20px;

// Font weights
$font-weight-light: 300;
$font-weight-regular: 400;
$font-weight-medium: 500;
$font-weight-semibold: 600;
$font-weight-bold: 700;

// Line heights
$line-height-tight: 1.2;
$line-height-normal: 1.5;
$line-height-loose: 1.8;

// Heading styles
.mat-typography h1,
.mat-typography h2,
.mat-typography h3,
.mat-typography h4,
.mat-typography h5,
.mat-typography h6 {
font-weight: bold;
font-family: $header-font-family;
}

// Enhanced heading sizes
.mat-typography h1 {
font-size: 32px;
line-height: $line-height-tight;
margin-bottom: 24px;
}

.mat-typography h2 {
font-size: 28px;
line-height: $line-height-tight;
margin-bottom: 20px;
}

.mat-typography h3 {
font-size: 24px;
line-height: $line-height-tight;
margin-bottom: 16px;
}

.mat-typography h4 {
font-size: 20px;
line-height: $line-height-tight;
margin-bottom: 16px;
}

.mat-typography h5 {
font-size: 18px;
line-height: $line-height-tight;
margin-bottom: 12px;
}

.mat-typography h6 {
font-size: 16px;
line-height: $line-height-tight;
margin-bottom: 12px;
}

// Body text styles
.mat-typography p {
font-family: $body-font-family;
font-size: $font-size-md;
font-weight: $font-weight-regular;
line-height: $line-height-normal;
margin-bottom: 16px;
}

// Button typography
.mat-button,
.mat-raised-button,
.mat-stroked-button,
.mat-flat-button {
font-family: $body-font-family;
font-size: $font-size-md;
font-weight: $font-weight-medium;
line-height: $line-height-tight;
letter-spacing: 0.5px;
}

// Form field typography
.mat-form-field {
font-family: $body-font-family;
font-size: $font-size-md;
line-height: $line-height-normal;
}

// Caption and hint text
.mat-caption,
.mat-hint {
font-family: $body-font-family;
font-size: $font-size-xs;
font-weight: $font-weight-regular;
line-height: $line-height-tight;
letter-spacing: 0.4px;
}

// Card typography
.mat-card-title {
font-family: $header-font-family;
font-size: $font-size-lg;
font-weight: $font-weight-medium;
line-height: $line-height-tight;
}

.mat-card-subtitle {
font-family: $body-font-family;
font-size: $font-size-sm;
font-weight: $font-weight-regular;
line-height: $line-height-tight;
color: rgba(0, 0, 0, 0.6);
}

// Tab typography
.mat-tab-label {
font-family: $body-font-family;
font-size: $font-size-sm;
font-weight: $font-weight-medium;
letter-spacing: 0.5px;
}

// Utility typography classes
.text-light {
font-weight: $font-weight-light;
}

.text-regular {
font-weight: $font-weight-regular;
}

.text-medium {
font-weight: $font-weight-medium;
}

.text-semibold {
font-weight: $font-weight-semibold;
}

.text-bold {
font-weight: $font-weight-bold;
}

.text-xs {
font-size: $font-size-xs;
}

.text-sm {
font-size: $font-size-sm;
}

.text-md {
font-size: $font-size-md;
}

.text-lg {
font-size: $font-size-lg;
}

.text-xl {
font-size: $font-size-xl;
}

.text-tight {
line-height: $line-height-tight;
}

.text-normal {
line-height: $line-height-normal;
}

.text-loose {
line-height: $line-height-loose;
}

// Specialized typography styles
.text-uppercase {
text-transform: uppercase;
letter-spacing: 1px;
}

.text-truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.text-center {
text-align: center;
}

.text-right {
text-align: right;
}

.text-muted {
color: rgba(0, 0, 0, 0.54);
}

3. Component-Specific Styling

// Button styling with M2 syntax
.mat-button, .mat-raised-button {
@include mat.button-color($custom-theme);
}

// Tab styling
.mat-tab-group {
@include mat.tabs-color($custom-theme);
}

// Form field styling
.mat-form-field {
@include mat.form-field-color($custom-theme);
}

4. How This Works in Latest Angular Versions

The latest Angular Material versions (16+) have transitioned to Material Design 3 (M3), but they maintain backward compatibility with Material Design 2 (M2) through special functions prefixed with m2-.

Key differences:

  1. Function naming:

    • M2: mat.m2-define-palette() and mat.m2-define-light-theme()
    • M3: mat.define-palette() and mat.define-light-theme()
  2. Theme structure:

    • M2: mat.m2-define-light-theme($primary, $accent, $warn)
    • M3: mat.define-light-theme((color: (primary: $primary, accent: $accent, warn: $warn), typography: $typography, density: 0))
  3. Component theming:

    • M2 uses component theming mixins like @include mat.button-color($theme)
    • M3 uses CSS custom properties

Using M2 in Latest Angular:

  1. Import Angular Material with @use

    @use '@angular/material' as mat;
  2. Use M2-specific functions with the m2- prefix

    $primary-palette: mat.m2-define-palette($custom-purple);
    $theme: mat.m2-define-light-theme($primary-palette, $accent-palette, $warn-palette);
  3. Apply themes with standard mixins

    @include mat.all-component-themes($theme);

5. Usage Examples

Button Example

<button mat-raised-button color="primary">Primary Button</button>
<button mat-raised-button color="accent">Accent Button</button>

Custom Component Styling

// In component.scss
@use '@angular/material' as mat;
@use 'path/to/your-theme' as theme;

.custom-card {
background-color: mat.get-color-from-palette(theme.$primary-palette, 100);
color: mat.get-color-from-palette(theme.$primary-palette, 900);
}

Using Color in Templates

<div class="custom-card">
This card uses custom theme colors
</div>

6. Best Practices

  1. Keep all theme definitions in a central theme file
  2. Use the provided M2 functions with m2- prefix for backwards compatibility
  3. For component-specific styling, use @include with appropriate mixins
  4. Extract color values with mat.get-color-from-palette() for custom components
  5. Consider using CSS custom properties for simple color overrides

This approach ensures your Material 2 theming works consistently in the latest Angular versions while maintaining the familiar Material 2 design system.