Create your account

Already have an account? Login here

Note: By joining, you will receive periodic emails from Coursetro. You can unsubscribe from these emails.

Create account

Create your own Angular 5 Material Theme

By Gary simon - Nov 15, 2017

Ready to build Awesome Angular Apps?

A Free Course, Free Tutorials and Full App Development Courses!

Great! Check your email

I've just sent you the first email to get you started.

With the reletively recent release of Angular 5, and the popularity of my Angular 5 Material tutorial, I thought I would create a tutorial that will show you how to customize your Angular 5 Material theme.

Out of the box, Angular Material provides you with 4 default themes to choose from. That's fine and all, but let's be honest, if you're working on a serious app, you probably need to customize the colors for the brand.

If you're new to Angular Material, I suggest you read/watch my Angular 5 Material tutorial where you will learn how to actually use and integrate material components. This video is strictly about customizing your theme.

Let's get started!

If you prefer watching a video tutorial..

Be sure to Subscribe to the Official Coursetro Youtube Channel for more videos.

Getting Started

I'm going to assume that you're already familiar with the Angular CLI and have it installed, along with Nodejs and NPM. If you're unfamiliar with anything I just said, watch our free Angular 5 from Scratch course.

Let's start a new project in the console and serve it by running these 3 commands:

$ ng new custom-theme --style=scss
$ cd custom-theme
$ ng serve

Integrating Angular Material

Open up a second console window, and within the custom-theme that was just created, run the following command to install Material:

$ npm install @angular/material @angular/cdk --save

Next, because some Material components rely on Angular animation, let's install that too:

$ npm install @angular/animations --save

We need to add the animations library to the imports array of ngModule within the src/app/app.module.ts file in the project:

Also: (While we're here, we will also import the Material components we will be using for this demo)

// Other imports removed for brevity
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule, MatToolbarModule, MatIconModule, MatCardModule } from '@angular/material';

@NgModule({
  ...
  imports: [
    ...,
    BrowserAnimationsModule,
    MatButtonModule,
    MatToolbarModule,
    MatIconModule,
    MatCardModule
  ],
  ...
})
export class AppModule { }

Great! Next, we need to integrate one of the 4 predefined themes into the /src/styles.css file:

@import "~@angular/material/prebuilt-themes/indigo-pink.css";

Finally, let's add the Material Icons font into */src/index.html* file:

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

We're ready to rock!

Defining the Template

I'm going to copy and paste some of the example template and CSS from the official Angular Material documentation for this demo.

Open up /src/app/app.component.html and paste the following HTML:

<mat-toolbar color="primary">
  <mat-toolbar-row>
    <span>Material App</span>
    <span class="example-spacer"></span>
    <mat-icon class="example-icon">favorite</mat-icon>
    <mat-icon class="example-icon">delete</mat-icon>
  </mat-toolbar-row>
</mat-toolbar>

<mat-card class="example-card">
  <mat-card-header>
    <div mat-card-avatar class="example-header-image"></div>
    <mat-card-title>Shiba Inu</mat-card-title>
    <mat-card-subtitle>Dog Breed</mat-card-subtitle>
  </mat-card-header>
  <img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
  <mat-card-content>
    <p>
      The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
      A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
      bred for hunting.
    </p>
  </mat-card-content>
  <mat-card-actions>
    <button mat-raised-button color="accent">LIKE</button>
    <button mat-raised-button color="accent">SHARE</button>
  </mat-card-actions>
</mat-card>

Again, nothing special is happening here. It's just some HTML pasted from the component examples in the docs.

Next, visit the /src/app/app.component.css file and paste the following CSS rulesets, which again, are from the docs associated with the template above:

.example-header-image {
    background-image: url('https://material.angular.io/assets/img/examples/shiba1.jpg');
    background-size: cover;
}

.example-icon {
    padding: 0 14px;
}

.example-spacer {
    flex: 1 1 auto;
}

Save it, and the result in the browser at http://localhost:4200 should be similar to:

Customizing the Material Theme

Finally, we've arrived at the exciting part. In order to customize the material theme, we need to create a single scss file.

Create a file in /src/ called theme.scss (or whatever you prefer).

Inside of it, we must import @angular/material/theming and include mat-core():

@import '~@angular/material/theming';
@include mat-core();

The first line imports all of the theming functionality, and the next includes the common styles.

Before we continue with this file, we have to add the /themes.scss file to the styles array of /.angular-cli.json file:

// Other code removed for brevity

      "styles": [
        "styles.scss",
        "theme.scss"     // Add this
      ],

At this point, if you save the project, you'll notice nothing changes. That's because we haven't defined a new pallete!

Let's do that now back in the /src/theme.scss file:

@import '~@angular/material/theming';
@include mat-core();

$custom-primary: mat-palette($mat-amber);

Alright, so what is all of this? You may have been expecting to set some hex color values, but no.. 

With Material, we define a pallete to use with the mat-palette mixin. The value you provide in the first argument is designated as $mat- and [the name of the pallete].

You get the name of the palletes from the official Material.io Documentation from the color palettes:

Notice at the top, each palette has a name. If you wanted to use the Deep Purple pallete for instance, you would specify:

$custom-primary: mat-palette($mat-deep-purple);

When you specify new themes, you must specify an accent color along with the primary color. As long as you have at least those two variables, you can then reference either the mat-light-theme() mixin or the mat-dark-theme() mixin, and pass in your primary and accent variables.

After that, you @include the angular-material-theme mixin and pass in the previous defined mat-light-or-dark-theme mixin variable. 

The full code should now look like this:

@import '~@angular/material/theming';
@include mat-core();

$custom-primary: mat-palette($mat-deep-purple);
$custom-accent:  mat-palette($mat-pink);

$custom-theme: mat-light-theme($custom-primary, $custom-accent);

@include angular-material-theme($custom-theme);

Save it, and the result should now look like this:

That's how you change palletes, but of course, you can do much more.

Changing to Material Design Dark Theming

Right now, our project is using the mat-light-theme mixin. To change it to the dark theme, we simply change the following:

// FROM
$custom-theme: mat-light-theme($custom-primary, $custom-accent);

// TO 
$custom-theme: mat-dark-theme($custom-primary, $custom-accent);

Save it, and now the project should look like this:

Expanding on Mat-Pallete

In our example, we only specified the first argument of mat-pallete(), which is the actual palette. 

It accepts 3 other optional arguments:

  • Default Color
  • Lighter Color
  • Darker Color

Let's modify our code to include a default color:

$custom-primary: mat-palette($mat-deep-purple, 50);

The "50" value comes from the list at Material.io Documentation for each pallete. Lower numbers provide for a lighter background with a dark foreground, and vice-versa.

The result should look like this:

Update the code to the following:

$custom-primary: mat-palette($mat-deep-purple, 600);
$custom-accent:  mat-palette($mat-lime, 100);

Additionally, you can provide an optional warning pallete if you wish by altering the code:

$custom-primary: mat-palette($mat-deep-purple, 600);
$custom-accent:  mat-palette($mat-lime, 100);
$custom-warn:    mat-palette($mat-red);

$custom-theme: mat-dark-theme($custom-primary, $custom-accent, $custom-warn);

Creating Multiple Themes

If you need to, you can define multiple themes and apply them via a class. Let's give it a try:

@import '~@angular/material/theming';
@include mat-core();

$custom-primary: mat-palette($mat-deep-purple, 600);
$custom-accent:  mat-palette($mat-lime, 100);
$custom-warn:    mat-palette($mat-red);

$custom-theme: mat-dark-theme($custom-primary, $custom-accent, $custom-warn);
@include angular-material-theme($custom-theme);


// ALTERNATIVE THEME

$alt-primary: mat-palette($mat-yellow);
$alt-accent:  mat-palette($mat-grey, 200);

$alt-theme: mat-dark-theme($alt-primary, $alt-accent);

.alternative {
    @include angular-material-theme($alt-theme);
}

To use this alternative theme, you must attach a class of alternative in a parent container within the template.

So, if you visit app.component.html, and wrapped all of the HTML in a parent div with the class of alternative, the result would look like this:

Theming Specific Components

Let's say for whatever reason, you only wanted to apply a theme to a specific component. In our case, let's say that component is a button:

// FROM
.alternative {
    @include angular-material-theme($alt-theme);
}

// TO
.alternative {
    @include mat-button-theme($alt-theme);
}

If you save this, the result will show the regular purple toolbar defined in $custom-theme with the alternative color theme applied to just the buttons.

You can find the full list of themable components here.

Conclusion

As you can see, you're able to quickly and easily modify the material design themes within your Angular project.

Hopefully, you were able to find this tutorial helpful. 


Share this post




Say something about this awesome post!