Custom Theme for Angular Material Components Series: Part 1 — Create a Theme
Tags: angular, material, theme, scss
Published: 2020-03-24 15:14:32

> _Updated version of this article is present at: [angular-material.dev](https://angular-material.dev/articles/angular-material-theming-system-complete-guide)_

<i>Learn how to Create and Apply Custom Theme to different Angular Material Components. 😎<i>

## Context

In this series, I will write about creating and applying [Custom Theme](https://material.angular.io/guide/customizing-component-styles) to different [Angular Material Components](https://material.angular.io/components/categories).

---

Few days back, I was going through question on stack-overflow. A question regarding applying same theme to `mat-sidenav` as `mat-toolbar` appeared to my feed. You can check the question in below link:

{% stackoverflow 54248944 %}

Although, I answered the question with sample code, I thought of expanding the same context to more components and make a nice formatted code-base. Which can be useful to my upcoming projects and yours, too.

By end of this series, you would have a nice idea about creating and applying your own Custom Theme for Angular Material Components.

## Summary

I have made the series of three articles. Below is the summary of what we will be doing:

### Part 1

1. Create an Angular Project using Angular CLI and add Angular Material
2. Understand Angular Material Custom Theme
3. Create Base Theme Files
4. Update Project Structure with few new modules
5. Create basic UI skeleton

### Part 2

Understand how Angular Material Theme works by a deep look into Angular Material’s repo.

### Part 3

1. Understand theme of MatToolbar
2. Apply `MatToolbar`’s theme to `MatSidenav` and `MatDialog` (we won’t be applying theme to whole dialog, just to it’s header)
3. Apply a different theme to `MatSnackbar` and create nice styling for different kind of notifications (default, info, success, warning, error)

---

Let's begin...

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dffsx48efxsx18zmmlf0.jpg)

## 1. Create an Angular Project using Angular CLI and add Angular Material

```bash
ng new theming-material-components --style=scss --skipTests=true --routing=true
```

Above command will create a project-folder named *theming-material-components*, with *scss* as our styling partner, *routing* and skipped testing. Once it’s done, just move to project directory and run below commands:

```bash
cd theming-material-components
ng serve -o
```

The output will be something like below:

![initial output](https://dev-to-uploads.s3.amazonaws.com/i/6qe5cdtdpl21lykj8cus.png)

Now, to add Angular Material, we will follow official guideline from : [Angular Material Getting Started](https://material.angular.io/guide/getting-started):

```bash
ng add @angular/material
```

When asked, use responses like below:

![responses when adding Angular Material](https://dev-to-uploads.s3.amazonaws.com/i/1yktjryx1jqe0ybvljwa.png)

That will add all necessary packages, update *index.html*, *main.ts*, *app.module.ts* and *style.scss* files.

## 2. Understand Angular Material Custom Theme

Let’s look at *style.scss* file:

```scss

// Custom Theming for Angular Material
// For more information: https://material.angular.io/guide/theming
@import '~@angular/material/theming';
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$theming-material-components-primary: mat-palette($mat-indigo);
$theming-material-components-accent: mat-palette($mat-pink, A200, A100, A400);

// The warn palette is optional (defaults to red).
$theming-material-components-warn: mat-palette($mat-red);

// Create the theme object (a Sass map containing all of the palettes).
$theming-material-components-theme: mat-light-theme($theming-material-components-primary, $theming-material-components-accent, $theming-material-components-warn);

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($theming-material-components-theme);

/* You can add global styles to this file, and also import other style files */

html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
```

Notice that Angular CLI has created a basic default theme for us. Comments in file are pretty much straight-forward, which will give you idea about how custom theming works. Below is the summary:

1. Create primary `$theming-material-components-primary`, accent `$theming-material-components-accent` and warn `$theming-material-components-warn` colors from [Material Color System](https://material.io/design/color/#color-usage-palettes).
2. Using above colors, create a lighter version of theme `$theming-material-components-theme` with the help of `mat-light-theme`.
3. Finally, include your custom theme in Angular Material’s Theme builder called `angular-material-theme`, which is responsible for making all your components’ themes in-align with your custom theme.

## 3. Create Base Theme Files

```scss
// theme.scss

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$theming-material-components-primary: mat-palette($mat-indigo);
$theming-material-components-accent: mat-palette($mat-pink, A200, A100, A400);

// The warn palette is optional (defaults to red).
$theming-material-components-warn: mat-palette($mat-red);

// Create the theme object (a Sass map containing all of the palettes).
$theming-material-components-theme: mat-light-theme($theming-material-components-primary, $theming-material-components-accent, $theming-material-components-warn);
```

You can change the colors as per your requirements, but I will keep them as defaults.

I will also create one more file named *custom-component-themes.scss* like below:

```scss
// custom-component-themes.scss

// import custom componenet themes

// you only have to add additional componenets here (instead of in every theme class)
@mixin custom-components-theme($theme) {}
```

Basically, this file will contain all of our components’ themes. We will talk about the same later on.

Let’s import both : *theme.scss* and *custom-component-themes.scss* in our main *styles.scss* and include their mixins, so our updated file will look like below:

```scss
// styles.scss
// Custom Theming for Angular Material
// For more information: https://material.angular.io/guide/theming
@import '~@angular/material/theming';
// Plus imports for other components in your app.

// Include the common styles for Angular Material. We include this here so that you only
// have to load a single css file for Angular Material in your app.
// Be sure that you only ever include this mixin once!
@include mat-core();

// import our custom theme
@import './theme.scss';

// import custom componenet themes
@import './custom-component-themes.scss';

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include angular-material-theme($theming-material-components-theme);
@include custom-components-theme($theming-material-components-theme);

/* You can add global styles to this file, and also import other style files */

html, body { height: 100%; }
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
```

To understand more about use of Material Colors in Creation of Custom Material Theme, you can read a nice article by [Tomas Trajan](https://medium.com/u/360cd444e1fc?source=post_page-----42229068271d----------------------):

{% medium https://medium.com/@tomastrajan/the-complete-guide-to-angular-material-themes-4d165a9d24d1 %}

## 4. Update Project Structure with few new modules

As of now, our project structure is something like below:

![Project Structure](https://dev-to-uploads.s3.amazonaws.com/i/zbjsb62hjh3ay7t57qta.png)
<figcaption>Project Structure After Step 3</figcaption>

Let’s create a module, which will have all of our Angular Material modules.

```bash
ng g m custom-material
```

That will create a file and folder : *custom-material/custom-material.module.ts* . Let’s add couple of modules from Angular Material modules in it:

```ts
// app/custome-material/custom-material.module.ts
import { NgModule } from "@angular/core";
import { MatSidenavModule } from "@angular/material/sidenav";
import { MatSliderModule } from "@angular/material/slider";
import { MatSlideToggleModule } from "@angular/material/slide-toggle";
import { MatToolbarModule } from "@angular/material/toolbar";

@NgModule({
  exports: [
    MatSidenavModule,
    MatSliderModule,
    MatSlideToggleModule,
    MatToolbarModule
  ]
})
export class CustomMaterialModule {}
```

Now, let’s create a shared module, which will be a home to all of our shared modules, components, directives, pipes and services.

```bash
ng g m shared
```

Now, let’s add our `CustomMaterialModule` in `imports` array of `SharedModule`:

```ts
// app/shared/shared.module.ts
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { CustomMaterialModule } from "../custom-material/custom-material.module";

@NgModule({
  declarations: [],
  imports: [CommonModule, CustomMaterialModule]
})
export class SharedModule {}
```

And let’s import `SharedModule` in `AppModule` :

```ts
// app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SharedModule } from './shared/shared.module'; // 🆕 <-- Added

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    SharedModule // 🆕 <-- Added
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

## 5. Create basic UI skeleton

Let’s create a shared component `SideNavComponent` which we will use in our `AppComponent`:

```bash
ng g c shared/components/sidenav
```

Let’s update the content of *sidenav.component.html* , *sidenav,component.scss* and *sidenav.component.ts* :

```html
// app/shared/components/sidenav/sidenav.component.html
<mat-toolbar [color]="themeColor">
  Toolbar
</mat-toolbar>
<mat-sidenav-container class="example-container">
  <mat-sidenav #sidenav mode="side" opened> Sidenav content</mat-sidenav>
  <mat-sidenav-content>
    <ng-content></ng-content>
  </mat-sidenav-content>
</mat-sidenav-container>
```

```scss
// app/shared/components/sidenav/sidenav.component.scss
.example-container {
  height: 500px;
}
```

```ts
// app/shared/components/sidenav/sidenav.component.ts
import { Component, OnInit, Input } from "@angular/core";

@Component({
  selector: "app-sidenav",
  templateUrl: "./sidenav.component.html",
  styleUrls: ["./sidenav.component.scss"]
})
export class SidenavComponent implements OnInit {
  @Input() themeColor = "";
  constructor() {}

  ngOnInit() {}
}
```

Notice the `@Input() themeColor` property of component. We will be using this property to assign same theme to sidenav and toolbar (and other component in next part).

Let’s add `SidenavComponent` to `exports` array of `SharedModule` :

```ts
// app/shared/shared.module.ts
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { CustomMaterialModule } from "../custom-material/custom-material.module";
import { SidenavComponent } from "./components/sidenav/sidenav.component";

@NgModule({
  declarations: [SidenavComponent],
  imports: [CommonModule, CustomMaterialModule],
  exports: [SidenavComponent] // 🆕 <-- Added
})
export class SharedModule {}
```

> ***👉 Pro Tip:*** *Don’t forget to export all the components/pipes/directives which we are going to make in `SharedModule`.*

Now, let’s remove everything from *app.component.html* and replace it like below:

```html
// app/app.component.html
<app-sidenav [themeColor]="'primary'">
  Main Content
</app-sidenav>
```

If you change the [themeColor] to warn or accent , it will change effectively:

![themeColor changes](https://dev-to-uploads.s3.amazonaws.com/i/m0r46rtoeu8mlt3mfm31.png)
<figcaption>themeColor = "primary" | "accent" | "warn"</figcaption>

Now, the project structure is something like below:

![Project Structure after Step 5](https://dev-to-uploads.s3.amazonaws.com/i/4l0mxgn2g0jzsuwp34r4.png)
<figcaption>Project Structure after Step 5</figcaption>

Phew..!! You are done with basic project setup. You deserve 3 claps… 👏 👏 👏

![Joker clapping](https://dev-to-uploads.s3.amazonaws.com/i/yj072txp4qvyljecc6s7.gif)

If you are thinking that we haven’t done much yet, I wouldn’t say you’re wrong. But, basic setup, custom theme introduction and understanding is needed before we move ahead.

---

## Thank You,

for reading this article. This was my first article on medium. Let me know your feedback in comments section.

In the next part we will learn how Angular Material’s Theme works. We will also take a deep look into Angular Material’s report and understand the relation between stylesheets.

> *Wait..!! Where’s the code man !!??*

Whatever we’ve created in this article, I have combined them as an Angular Project, and uploaded on GitHub:

{% github shhdharmen/theming-material-components-part-1 %}

Next part is also published:

{% post https://dev.to/shhdharmen/custom-theme-for-angular-material-components-series-part-2-understand-theme-aa2 %}

That’s it, see you next time. And yes, always believe in yourself.

![Always believe in yourself](https://dev-to-uploads.s3.amazonaws.com/i/e9syoo6qndgrim6ps637.jpg)

### Credits
<small>Cover image credit <a target="_blank" rel="noopener" href="https://photos.icons8.com/photos/minute-on-the-lips-lifetime-on-the-hips--5ac5dcff8b658800017f7f5d">Photo</a> by <a target="_blank" rel="noopener" href="https://photos.icons8.com">Moose</a>
Begin image credit: Photo by <a href="https://unsplash.com/@dsmacinnes?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Danielle MacInnes</a> on <a href="/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a>
Footer image credit: [link](https://quotefancy.com/quote/34647/Sun-Tzu-You-have-to-believe-in-yourself)</small>