How to Create Custom Theme in Angular Material

Last updated on: by Digamber
In this Angular Material custom theme example tutorial, we will explore how to create custom theme in Angular Material from scratch in less than 5 minutes. Angular material offers pre-built ui themes with primary, warning, and accent color options.

If you are working on a real-world angular application, in that case, you might need to create a custom angular material theme to make your project brand look better.

Let’s understand what theme is according to Angular material. An Angular material theme is the set of colors that will be applied to the Angular Material components. Angular material theme is built on the material design pattern.

Get Started with Angular Project Setup

I assume you already have set up Node JS, NPM & Angular CLI in your system. Let’s get started and set up the Angular project.

ng new angular-material8-theme
# ? Would you like to add Angular routing? Yes
# ? Which stylesheet format would you like to use? SCSS

Go inside project folder.

cd angular-material8-theme

Implementing Angular Material UI Library

Run the given below command to install Material library:

ng add @angular/material

Select any theme among Angular Material Pre-built Themes:

? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink
❯ Indigo/Pink        [ Preview: https://material.angular.io?theme=indigo-pink ] 
  Deep Purple/Amber  [ Preview: https://material.angular.io?theme=deeppurple-amber ] 
  Pink/Blue Grey     [ Preview: https://material.angular.io?theme=pink-bluegrey ] 
  Purple/Green       [ Preview: https://material.angular.io?theme=purple-green ]

Select Yes for including Angular Material Typography and Animations packages.

# ? Set up global Angular Material typography styles? Yes
# ? Set up browser animations for Angular Material? Yes

Complete Angular material 8 documentation can be found here.

Create Angular Material Module File

Let’s create a separate Angular material module file. to manage Angular material UI components.

Go to angular-material.module.ts file and include the following code.

import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { OverlayModule } from '@angular/cdk/overlay';
import { CdkTreeModule } from '@angular/cdk/tree';
import { PortalModule } from '@angular/cdk/portal';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';
import { MatRippleModule } from '@angular/material/core';
import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTreeModule } from '@angular/material/tree';
import { MatBadgeModule } from '@angular/material/badge';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatRadioModule } from '@angular/material/radio';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatTooltipModule } from '@angular/material/tooltip';

const materialModules = [
  CdkTreeModule,
  MatAutocompleteModule,
  MatButtonModule,
  MatCardModule,
  MatCheckboxModule,
  MatChipsModule,
  MatDividerModule,
  MatExpansionModule,
  MatIconModule,
  MatInputModule,
  MatListModule,
  MatMenuModule,
  MatProgressSpinnerModule,
  MatPaginatorModule,
  MatRippleModule,
  MatSelectModule,
  MatSidenavModule,
  MatSnackBarModule,
  MatSortModule,
  MatTableModule,
  MatTabsModule,
  MatToolbarModule,
  MatFormFieldModule,
  MatButtonToggleModule,
  MatTreeModule,
  OverlayModule,
  PortalModule,
  MatBadgeModule,
  MatGridListModule,
  MatRadioModule,
  MatDatepickerModule,
  MatTooltipModule
];
@NgModule({
  imports: [
    CommonModule,
    ...materialModules
  ],
  exports: [
    ...materialModules
  ],
})
export class AngularMaterialModule { }

Import Angular Material module file inside the app.module.ts file.

/* Angular material */
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AngularMaterialModule } from './angular-material.module';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@NgModule({
  declarations: [...],
  imports: [
    BrowserAnimationsModule,
    AngularMaterialModule,
  ],
  providers: [...],
  bootstrap: [...],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }

We are done with all setup now we’re ready to go!

Create Angular Material 8 Basic Layout

In order to create a basic template, we should go to Angular Material official site and check out the UI components there.

Go to app.component.html file and paste the following code.

<!-- Toolbar -->
<mat-toolbar color="primary" class="header">
  <div>Material Theme</div>
  <span class="nav-tool-items">
    <mat-icon (click)="sidenav.toggle()" class="hamburger">menu</mat-icon>
  </span>
</mat-toolbar>
<mat-sidenav-container>
  <!-- Sidenav -->
  <mat-sidenav #sidenav [mode]="isBiggerScreen() ? 'over' : 'side'" [(opened)]="opened" [fixedInViewport]="true"
    [fixedTopGap]>
    <mat-nav-list>
      <a mat-list-item>
        <mat-icon>dashboard</mat-icon> Dashboard
      </a>
      <a mat-list-item>
        <mat-icon>person</mat-icon> User Profile
      </a>
      <a mat-list-item>
        <mat-icon>content_paste</mat-icon> Table List
      </a>
      <a mat-list-item>
        <mat-icon>library_books</mat-icon> Typography
      </a>
      <a mat-list-item>
        <mat-icon>location_on</mat-icon> Maps
      </a>
      <a mat-list-item>
        <mat-icon>calendar_today</mat-icon> Calendar
      </a>
    </mat-nav-list>
  </mat-sidenav>
  <!-- Main content -->
  <mat-sidenav-content>
    <!-- Applying the mat-tyography class adds styles for native elements. -->
    <section class="mat-typography title-group">
      <h1>Heading Goes Here</h1>
      <mat-divider></mat-divider>
    </section>
    <!-- Angular material cards -->
    <div class="productCards">
      <mat-grid-list cols="4" rowHeight="200px">
        <mat-grid-tile [colspan]="3" [rowspan]="1">1
        </mat-grid-tile>
        <mat-grid-tile [colspan]="1" [rowspan]="2">2
        </mat-grid-tile>
        <mat-grid-tile [colspan]="1" [rowspan]="1">3
        </mat-grid-tile>
        <mat-grid-tile [colspan]="2" [rowspan]="1">4
        </mat-grid-tile>
      </mat-grid-list>
    </div>
  </mat-sidenav-content>
</mat-sidenav-container>

Go to app.component.ts file and paste the following code.

import { Component, ViewChild, HostListener } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  opened = true;
  @ViewChild('sidenav', { static: true }) sidenav: MatSidenav;
  ngOnInit() {
    console.log(window.innerWidth)
    if (window.innerWidth < 768) {
      this.sidenav.fixedTopGap = 55;
      this.opened = false;
    } else {
      this.sidenav.fixedTopGap = 55;
      this.opened = true;
    }
  }
  @HostListener('window:resize', ['$event'])
  onResize(event) {
    if (event.target.innerWidth < 768) {
      this.sidenav.fixedTopGap = 55;
      this.opened = false;
    } else {
      this.sidenav.fixedTopGap = 55
      this.opened = true;
    }
  }
  isBiggerScreen() {
    const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    if (width < 768) {
      return true;
    } else {
      return false;
    }
  }
}

Now, go to terminal and run the below command to run your project.

ng serve --open

Angular Material 8 Theme

If every thing goes fine, you’ll get this output.

Creating Angular Material 8 Custom Theme

We are going to create a custom theme in Angular material; first, we need to create a custom theme.scss file and keep it in src/ folder.

"styles": [
     "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
     "src/styles.scss",
     "src/theme.scss"
]

Please don’t forget to restart the server. When you make any changes in the angular.json file. Otherwise, changes won’t reflect in your Angular project.

Press "control" + "c" twice then run the following command in your terminal.

ng serve

To create a custom theme in Angular material, you’ll have to import the theming service from the Angular Material and add the base style like given below.

@import '~@angular/material/theming';
@include mat-core();
/* ======== Angular material custom themes ======== */  

The mat-palette function takes some parameters to define a new theme. In the 1st parameter, we pass the palette color name along with $mat-(color palette name). We pass lighter values in the rest of the parameters.

To style primary, accent, and warning color themes you must declare the color variables name using the mat-palette function.

You can take palette color names reference from the Material.io official website.

@import '~@angular/material/theming';
@include mat-core();
/* ======== Angular material custom themes ======== */ 
$my-custom-primary: mat-palette($mat-deep-purple);
$my-custom-accent: mat-palette($mat-pink, 100, 500, A100);
$my-custom-warn: mat-palette($mat-lime);
$my-custom-theme: mat-light-theme($my-custom-primary, $my-custom-accent, $my-custom-warn);
@include angular-material-theme($my-custom-theme);

If you are creating a custom theme in Angular Material so it will be a good practice you define primary, accent and warn theme altogether.

You’ll get the given below output if you check in the browser.

Angular Material Custom Theme

We wrap up our custom Angular material theme in the $my-custom-theme variable. As you can see, we’ve added our custom theme’s color definition in mat-light-theme() function. In the final step, we are passing $my-custom-theme inside the angular-material-theme() method.

Create Angular Material Dark Theme

At the moment, we are using mat-light-theme() mixin function. Now here comes the easy part, we can create a dark angular material theme by just using the mat-dark-theme() mixin.

Creating a dark Angular Material theme is pretty easy and straight-forward task. You just have to follow the given below process.

// Convert => mat-light-theme()
$my-custom-theme: mat-light-theme($my-custom-primary, $my-custom-accent);
// Convert to this => mat-dark-theme()
$my-custom-theme: mat-dark-theme($my-custom-primary, $my-custom-accent);

Check out the demo:

Create Angular Material Dark Theme

Create Alternative Themes in Angular Material 8

Creating an alternate theme in angular material 8 is not that difficult. All you have to do just declared the alternate theme in your theme.scss file like given below.

The my-alternate-theme class name should be defined within a class element in the HTML template. You can check out in the example below how we have defined the class name in the parent HTML element, and the alternate theme is working fine.

Go to app.component.html file and add the below code.

// Alternate Angular Material Theme
.my-alternate-theme {
  $my-alternate-primary: mat-palette($mat-red);
  $my-alternate-accent: mat-palette($mat-green, 400);
  $my-alternate-warn: mat-palette($mat-grey);
  $my-alternate-theme: mat-light-theme($my-alternate-primary, $my-alternate-accent, $my-alternate-warn);
  @include angular-material-theme($my-alternate-theme);
}

Then go to app.component.html file and add the following code.

<mat-card class="my-alternate-theme">
   My Alternate Themes:
   <button mat-raised-button color="primary">Primary</button>
   <button mat-raised-button color="accent">Accent</button>
   <button mat-raised-button color="warn">Warning</button>
</mat-card>

Below will be the output:

Alternative Themes in Angular Material 11

If you need any help related to this tutorial then you can found the GitHub.

Don’t forget to share this tutorial if you found this useful, thanks for checking this tutorial out.

Have a good day.

Digamber

I am Digamber, a full-stack developer and fitness aficionado. I created this site to bestow my coding experience with newbie programmers. I love to write on JavaScript, ECMAScript, React, Angular, Vue, Laravel.