Getting Started with Angular Material 2
This article will show you how to setup your Angular project (v2+) using Angular Material 2.
Update December 2017: code updated to Angular v5+ and Material v5+. Stackblitz link also available at the end of this article.
Update May 2018: code updated to Angular v6 and added new section about CLI v6.
Contents
1: Create your Angular project with Angular CLI
The first step is creating your Angular project using Angular CLI.
For this example we will use the following command:
ng new angular-material-example --routing -is -st -style=scss
With the command above, we are asking Angular CLI to create a new project with a routing module (--routing
), use inline style (-is
) for app.component.ts
, skip the creation of unit testing files (-st
) - since we will not need .spec
file for this example and also use scss
as extension for our style/CSS files.
It will create a new project with the following files:
2: npm install @angular-material and hammerjs
Next, we need to install @angular-material and its required dependencies. Change the directory to the project we created (cd angular-material-example
) and execute the following command:
npm install --save @angular/material @angular/cdk hammerjs
2.1: ng add @angular/material (Angular v6+)
Since Angular v6 and Angular CLI v6, a new command is available to automatically install and configure Angular Material: ng add @angular/material
. This command will install do the following:
- install Angular material and animations package using your package manager
- include a theme in
angular.json
- add the import for Material Icons and
Roboto
font in theindex.html
- add
BrowserAnimationsModule
import to theapp.module.ts
file
By using the ng add @angular/material
command, three material components will be available in Angular CLI through schematics:
ng generate @angular/material:material-nav --name=my-nav-name
ng generate @angular/material:material-dashboard --name=my-dashboard-name
ng generate @angular/material:material-table --name=my-table-name
Personally, I still prefer importing the theme and Material Icons as described at section #4 of this article, so I use the ng add
command and remove the imports from index.html
and angular.json
3: Configure angular.json and hammerjs
Hammer.js
is an optional dependency and helps with touch support for a few of the components (mat-slide-toggle
, mat-slider
, atTooltip
).
I like to always include hammerjs
as a dependency as well. And we also need to include its import in angular-cli.json
. Locate the scripts
section and add the hammer.min.js
import:
"scripts": [
"node_modules/hammerjs/hammer.min.js"
],
Note: if you are using Angular v5 or below, please use the following code instead in angular-cli.json
(as some structure files were updated in Angular v6+):
"scripts": [
"../node_modules/hammerjs/hammer.min.js"
],
4: Include a theme and Material Icons
To add a theme to our project, open src/style.css
or src/style.scss
and add:
@import '~@angular/material/prebuilt-themes/indigo-pink.css';
Angular Material 2 comes with 4 pre built themes: indigo-pink
, deeppurple-amber
, purple-green
and pink-bluegrey
.
You can replace indigo-pink.css
with any of the options mentioned above.
By using
ng add @angular/material
, the theme will be automatically imported inangular.json
, so no need to add to your css or scss.
Material Icons
If you need to use icons in your application, you can also import Material Design icons.
If you are using css
as file extension, include the following in your src/style.css
before the material theme import:
@import '~https://fonts.googleapis.com/icon?family=Material+Icons';
If you are using scss
as file extension, include the following import in your src/style.scss
file (before the material theme import):
@import url('https://fonts.googleapis.com/icon?family=Material+Icons');
By using
ng add @angular/material
, the icons will be automatically imported inindex.html
, so no need to add to your css or scss.
Local support to Material Icons
If you prefer to host Material Icons locally, you can also follow the next steps.
First, install material-design-icons
from npm:
npm install material-design-icons --save
In your src/style.css
add the following import:
@import '~material-design-icons/iconfont/material-icons.css';
And that’s it!
5: Configure app.module
Some Angular Material components depend on @angular/animations
package. Open your package.json
and confirm if it has been already installed (Angular CLI already adds it as a dependency along with other @angular
packages). If it is not installed, then install it with the command below:
npm install --save @angular/animations
Make sure you use the same version as the other @angular
packages.
Open app.module.ts
and configure the animations package.
If you would like Material components to be animated, then add BrowserAnimationsModule
to the app.module imports
section:
//other EcmaScript imports
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
imports: [
//other imports
BrowserAnimationsModule
]
})
export class AppModule { }
If you would not like to use animations, then replace BrowserAnimationsModule
with NoopAnimationsModule
in the code above.
By using
ng add @angular/material
, theBrowserAnimationsModule
will be automatically added toapp.module.ts
.
6: Using Material Components
Now the setup is already in place and we can start coding!
We can open app.component.html
and start adding our Material components HTML tags. But we will do some extra steps so we have a project a little bit more organized.
Creating a HomeComponent page
Let’s create a new module and component using Angular CLI:
ng g m home --routing
With the command above the following files will be created:
├── home
| ├── home-routing.module.ts
| ├── home.module.ts
Now let’s also create a HomeComponent:
ng g c home/home -s
The
-s
flag will skip creating the.scss
file and will use inline styles in the component.
Open home.component.html
add add the following code:
<mat-toolbar color="primary">
<span>Angular Material Example</span>
</mat-toolbar>
If you are using VSCode and the Angular Languague Service extension, you will get some compilation errors in your HTML template:
This is because the mat-*
components are not known by Angular, hence we need to import them in our module.
Please note that Angular Material RC changed its prefix from
md
tomat
We can verify in the Angular Material docs which are the Material modules we need to import in our project.
For the mat-toolbar
, we can go to Toolbar API tab link and we will see that we need to import MatToolbarModule
.
We have two options. The first one is importing MatToolbarModule
in the home.module.ts
file:
import { MatToolbarModule } from '@angular/material/toolbar';
@NgModule({
imports: [
CommonModule,
HomeRoutingModule,
MatToolbarModule
],
declarations: [HomeComponent]
})
export class HomeModule { }
Creating a shared MaterialModule for our project
Suppose we have another module that is also going to use the mat-toolbar
component. We would need to import MatToolbarModule
again in that module.
To avoid repeating the same import in several different modules in our project, we are going to create a shared MaterialModule (this is the second option, and I personally prefer using this one). This way, we only need to import the component we need once and we can import this module in any other module that is needed.
To do so, we will use Angular CLI to create a new module:
ng g m app-material
We will add any Material module in this module. Let’s start with the MatToolbarModule
:
import { CommonModule } from '@angular/common';
import { MatToolbarModule } from '@angular/material/toolbar';
@NgModule({
exports: [
MatToolbarModule
]
})
export class AppMaterialModule { }
Note that we will add any Material Module we need for this project in the exports
metadata.
Now we can go back to the home.module
and import the shared Material module we created:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HomeRoutingModule } from './home-routing.module';
import { HomeComponent } from './home/home.component';
import { AppMaterialModule } from './../app-material/app-material.module';
@NgModule({
imports: [
CommonModule,
HomeRoutingModule,
AppMaterialModule
],
declarations: [HomeComponent]
})
export class HomeModule { }
Configuring the routes and app.component
Since we created a home.component
, this is going to be the main Component for the home.module
. So we need to add the home.component
in our HomeRoutingModule
:
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{ path: '', component: HomeComponent }
];
Angular CLI generates app.component.ts
with some starter code. For this example, we will only need the router-outlet
tag, so we can simplify the code for app.component.ts
:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: '<router-outlet></router-outlet>',
styles: []
})
export class AppComponent {}
Since our template has only 1 line of code, it is OK to use the inline template (the Angular style guide says inline template is ok up to 3 lines of code).
And as a last step of our basic configuration, we need to add a routing path to the HomeModule in the app-routing.module.ts
:
const routes: Routes = [
{
path: '', loadChildren: './home/home.module#HomeModule'
}
];
When we load our application in the browser (path ‘’), the HomeModule will be lazy loaded and the HomeComponent will be rendered.
If we execute ng serve
and open http://localhost:4200/
we will be able to see a purple-ish toolbar:
Our code now has the following structure:
This is the project structure I usually use for my Angular Material projects. Now you can add more components and modules as needed and have fun with Material components!
Adding more Material Components to home.component.html
Let’s go back to home.component.html
and enhance our example. Our template should have the following code:
<mat-toolbar color="primary">
<button mat-icon-button [matMenuTriggerFor]="menu">
<mat-icon>more_vert</mat-icon>
</button>
<span>Angular Material Example</span>
<mat-menu #menu="matMenu">
<button mat-menu-item>
<mat-icon>dialpad</mat-icon>
<span>Menu 1</span>
</button>
<button mat-menu-item disabled>
<mat-icon>voicemail</mat-icon>
<span>Menu 2</span>
</button>
<button mat-menu-item>
<mat-icon>notifications_off</mat-icon>
<span>Menu 3</span>
</button>
</mat-menu>
</mat-toolbar>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Angular</mat-card-title>
<mat-card-subtitle>Material 2</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://loiane.com/images/tags/angular.svg" height="300px">
<mat-card-content>
<p>
Material Design components for Angular
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
We also need to go back to app-material.module.ts
and add the additional Material components we are using the HTML code above:
import { NgModule } from '@angular/core';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatCardModule } from '@angular/material/card';
@NgModule({
exports: [
MatToolbarModule,
MatIconModule,
MatButtonModule,
MatMenuModule,
MatCardModule
]
})
export class AppMaterialModule { }
After the changes above, this will be the output in the browser:
Tip: Angular Material VSCode Extension
VSCode has a very good extension to work with Angular Material components.
In the HTML templates we can simply type mat-
and the extension provide code snippets for the components available in angulat material.
This is the extension I use: Angular Material 2, Flex layout 1, Covalent 1 & Material icon snippets.
This extension is also part of the Angular extension package I created to work with Angular projects: Angular Extension Pack
Source code + live demo + Stackblitz
Source code available on GitHub
References:
Happy coding!