Build beautiful websites with Angular and Material Design
Tags: angular, material, design, scss
Published: 2020-10-02 07:16:55

Making stunning websites with a coherent design, colors, typography and animations has never been easier than now. 

In this blog post we will take a quick dive into [Angular](https://angular.io/) and [Angular Material](https://material.angular.io/) to illustrate how easy it is to get started. We will show the strengths of using Angular Material theming and create our own theme. We will also highlight other benefits of using [Material Design](https://material.io/) such as the design kits that comes for eg. [Adobe XD](https://www.adobe.com/products/xd.html) for effectively designing mockups and prototyping, as well as mention common used helpers that comes with Angular Material.

[Angular](https://angular.io/) is one of the most popular web frameworks used right now, it is type-script based, open-source, and it is led by the Angular Team at Google.

[Material Design](https://material.io/) is a design framework also developed by Google, which contains guidelines, components and tools that support best practices of user interface design.

[Angular Material](https://material.angular.io/) is an implementation of Material Design for Angular. It features many [plug-and-play components and styling](https://material.angular.io/components/categories) for buttons, input fields, tables, date pickers, cards and much more, as well as offer a way to create and customize the theme of your website.

What we'll end up with in this blog post is a login page implemented in Angular that utilizes Angular Material thus using the Material Design specification. I'll show how quick you can get started with Angular and Angular Material, and how you can build your Angular application such that changes in the theme will also update all your components themes at once:

![dark-theme](https://dev-to-uploads.s3.amazonaws.com/i/37aaalrshn6xihacoj2k.gif)

You may choose to follow along yourself or look at the final code [here](https://github.com/PeterOeClausen/angular-material-design-components-example-app). 

Finally, I will also include some ressources that can go hand-in-hand with your Angular application and Material Design.

Sidenote: If you're using React, [Material-UI](https://material-ui.com/) is another implementation of Material Design made for React. Material Design is also available for [Android, iOS, Flutter and as CDN](https://material.io/develop), but today we'll only be looking at Angular Material.

Let's dive in! :swimmer:

## Setup

In the following 3 easy steps, we will install Node and Angular, create and run an Angular application, and enable Angular Material.

### Step 1 - Install NodeJS:
Install NodeJS: https://nodejs.org/

### Step 2 - Install Angular and create an Angular project:
In your OS terminal execute the following commands:
```sh
# Install Angular using the Node Package Manager:
npm install -g @angular/cli
# Create a new Angular application named "example-app" using the Angular CLI using scss as stylesheet and with Angular routing enabled:
ng new example-app --style=scss --routing
# Change directory into the project directory:
cd example-app
# Run the Angular development server locally:
ng serve
```
I prefer SCSS, which is similar to CSS, so I picked that, but you can remove `--style=scss` and use CSS instead if you want, but note that we'll be using SCSS in this guide.

After running `ng serve` we should now have an Angular project running on `localhost:4200` that we can access in our web browser, eg. Google Chrome. You can stop the development server again by typing "ctrl + c" in the terminal running the server or by closing the terminal window.

![chrome_E4dSTIVUau](https://dev-to-uploads.s3.amazonaws.com/i/7317gb12iqus48x1uou3.png)

### Step 3 - Add Angular Material:
```sh
ng add @angular/material
```

Angular Material comes with the Indigo/Pink theme by default which is the one you're seeing on the [Angular Material homepage](https://material.angular.io/). More on Angular Material theming later.

This concludes our 3-step setup.

We now have an Angular application with Angular Material installed using the default indigo/pink theme, and we can run it with the `ng serve` command.

## Using Angular Material Components

Angular Material comes with many Angular components and styling, each type of component in their own module.

In Angular, a component usually consists of 3 files: The `name.component.html` file called the "template", the `name.component.scss` file containing styling for your template, and the `name.component.ts` file which contains a typescript class, which references the HTML and SCSS.

The `name.component.spec.ts` contains tests for the component but is not part of the component itself.

You can think of an Angular Material component as a button with a default style, which you can easily customize and use in your Angular application. In Angular, you can build components with components, eg. a login page component consisting of a button component and several input components.

A module in Angular is a lazy-loaded collection of components. You can import an Angular Material module in your applications module (`app.module.ts`) to get access to all the Angular Material components which it contains and use these Angular Material components in your application components.

You can get an overview of all Angular Material components [here](https://material.angular.io/components/categories). 

For now, let's make a component in Angular that uses a Material raised button `mat-raised-button`:

### Creating a new component in Angular

First we make a component:

```sh
ng generate component login
```

We'll eventually end up making a login page, so for now we've named our component "login".

This Angular CLI command generates 4 files: `login.component.html`, `login.component.scss`, `login.component.ts` and `login.component.spec.ts` for us.

In `app.component.html` I got rid of the Angular template html so it looks like this:
```html
<router-outlet></router-outlet>
```

The `<router-outlet>` will render the component which we specify in `app-routing-module.ts`.

We don't want to show the template html above our login component, that is why we remove the template code above it.

Next, we add a route to `app-routing.module.ts` that points to our newly created `Login` component when our url path is `localhost:4200/login`:
```ts
const routes: Routes = [
  { path: 'login', component: LoginComponent }
];
...
```

We can check that our component is rendered by accessing `localhost:4200/login` while our local development server is running. We should be seeing "login works" displayed:

![login-works](https://dev-to-uploads.s3.amazonaws.com/i/dg0xd558g2zh4f2sbfs3.PNG)

### Adding a raised Material button

To add a Material button we consult the [Angular Material documentation on buttons](https://material.angular.io/components/button/api). Under the API tab it says we need to add the `MatButtonModule`. And we'll do that in `app.module.ts`:

```ts
...
import { MatButtonModule } from '@angular/material/button';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
    MatButtonModule
  ],
  ...
})
export class AppModule { }
```

Then we can add a button to our `login.component.html` like so:
```html
<button mat-raised-button color="primary" (click)="onButtonClick()">Click me!</button>
```

And a button handler in `login.component.ts` like so:
```ts
export class LoginComponent implements OnInit {
  ...
  onButtonClick(){
    console.log("Clicked");
  }
}
```

When we go to `localhost:4200/login` in our browser we should see the login component. We now have a button that plays a ripple animation when we click on it:

![GMN6BRyQLn](https://dev-to-uploads.s3.amazonaws.com/i/7qjb3zsot789yh30jk0d.gif)

Not only that, as we used the `mat-raised-button` attribute, the button is "raised" having a box-shadow to stand out more on the page. And the color of the button is the selected theme's primary color. Awesome!

Alternatively, we could have used `mat-button` or `mat-stroked-button` to change the appearance of the button. And we could have used `color="accent"` to make the button pink (our secondary theme color) or `color="warn"` to make it red. For an overview of different button designs [see examples in the documentation](https://material.angular.io/components/button/overview).

### Adding input fields

Let's add some input fields for a username and password:

We import `MatInputModule` and `MatFormFieldModule` into `app.module.ts` and begin using [Angular Material form fields](https://material.angular.io/components/form-field/overview):

```ts
...
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
    MatInputModule,
    MatFormFieldModule
  ],
  ...
})
export class AppModule { }
```

And now we can start using the Angular Material components in our `login.component.html` like so:

```html
<div class="wrapper">
    <h1>Login</h1>

    <mat-form-field appearance="outline">
        <mat-label>Username</mat-label>
        <input matInput placeholder="x@it-minds.dk" type="text" 
            autocomplete="off" [(value)]="username" required/>
    </mat-form-field>

    <mat-form-field appearance="outline">
        <mat-label>Password</mat-label>
        <input matInput type="password" [(value)]="password" required/>
    </mat-form-field>

    <button mat-raised-button color="primary" (click)="onButtonClick()">Log in</button>
</div>
```

I also added `username` and `password` variables to `login.component.ts`:
```ts
...
export class LoginComponent implements OnInit {
  ...
  username = "";
  password = "";
  ...
}
```

And using [flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) in `login.component.scss` to center our content on the page, as well as put the contents in a column order:

```scss
// Center content vertically and horizontally:
:host{
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

// Display content in a column
.wrapper{
    display: flex;
    flex-direction: column;
    h1{
        // Adjust margin-bottom:
        margin-bottom: 1rem;
    }
}
```

The result can be seen below:

![login](https://dev-to-uploads.s3.amazonaws.com/i/gx9lw19kgi3lz6sufuap.gif)

As you can see, adding and using new material components is really easy. They look fantastic, and can easily be customized to fit the look and feel of the website you're working on.

The value that the user enters in Username and Password input fields is available in the `username` and `password` variables in the component class. But in this blog post we're only focusing on appearance.

## Enter Angular Material Theming :art:

Now we know how to import Angular Material modules and use them in our components, but what if we wanted to use values from theming to style our own components, say we wanted the "Login" `<h1>` to be the primary color of our theme. Is that possible? Yes! Let's do it:

### Extracting SCSS values from current theme

In our global styling stylesheet `styles.scss` we can add:
```SCSS
@import '~@angular/material/theming';

$primary-palette: mat-palette($mat-indigo);
...
```

I'm using the `$mat-indigo` SCSS variable because I know we're using the default indigo-pink theme.

`$mat-indigo` is a SCSS variable containing a color palette we import from Material theming (more on palettes soon).

`mat-palette()` is a SCSS function that we import from Material theming.

The `$primary-palette` SCSS variable is now assigned to the color palette of `$mat-indigo`.

Now we need to extract the primary color (indigo) from our `$primary-palette` variable. And we can do that in `login.component.scss` like so:

```SCSS
@import '../../styles.scss';

h1{
    color: mat-color($primary-palette);
}
```

`mat-color()` is a SCSS function for extracting colors from palettes, imported from material theming through our `styles.scss`.

And look, our "Login" `<h1>` is now using the primary color of our theme (indigo):

![login-using-theming](https://dev-to-uploads.s3.amazonaws.com/i/s8size8y3h39q7kvo4iz.PNG)

### Making our own theme - Enter dark theme :sunglasses:

Material design works with color palettes. If we navigate to `~@angular/material/theming` (ctrl + left-mouse-click in VS CODE) we enter Angular Material's SCSS styling from where we imported our functions and variables before, and we can see that the `$mat-indigo` palette is defined as: 

```SCSS
$mat-indigo: (
  50: #e8eaf6,
  100: #c5cae9,
  200: #9fa8da,
  300: #7986cb,
  400: #5c6bc0,
  500: #3f51b5,
  600: #3949ab,
  700: #303f9f,
  800: #283593,
  900: #1a237e,
  A100: #8c9eff,
  A200: #536dfe,
  A400: #3d5afe,
  A700: #304ffe,
  contrast: (
    50: $dark-primary-text,
    100: $dark-primary-text,
    200: $dark-primary-text,
    300: $light-primary-text,
    400: $light-primary-text,
    500: $light-primary-text,
    600: $light-primary-text,
    700: $light-primary-text,
    800: $light-primary-text,
    900: $light-primary-text,
    A100: $dark-primary-text,
    A200: $light-primary-text,
    A400: $light-primary-text,
    A700: $light-primary-text,
  )
);
```

There are many color palettes like it to choose from.

Say we wanted to create a dark theme for our website, is it hard to change? Well, let's try:

In our global `styles.scss` we add:
```scss
@import '~@angular/material/theming';

// Includes all common styles that are used by multiple Angular Material components
@include mat-core();

// Define your application's custom theme.
$primary-palette: mat-palette($mat-teal); //Note: Changed from mat-indigo
$accent-palette:  mat-palette($mat-pink, A200, A100, A400);
$theme: mat-dark-theme(  
  $primary-palette,
  $accent-palette,  
);

// Include theme styles for Angular Material components and each component used in your app.
@include angular-material-theme($theme);
...
```

And to make the background of our website respond to the dark-theme we also need to add the class `mat-app-background` to our `<body>` tag in index.html:

```html
<body class="mat-typography mat-app-background">
  <app-root></app-root>
</body>
```

And voila! Dark theme:

![dark-theme](https://dev-to-uploads.s3.amazonaws.com/i/37aaalrshn6xihacoj2k.gif)

Notice - as we used the primary palette when styling our "Login" `<h1>`, it also changed color to teal as we changed from the `$mat-indigo` palette to the `$mat-teal` palette. That means as long as we "tab into" our theming when styling our components, our components will also update with changes to the theme. Very cool.

With Angular Material we can even have multiple themes and have the user switch between them - all components (including our own) which uses Material theming (like our `<h1>`) will update with the change. The Angular Material documentation have a theme switcher in the top right of the website if you want to see an example of switching between themes.

Similarly, you are also able to [customize typography](https://material.angular.io/guide/typography), or eg. customize the shape of buttons (with eg. css `border-radius`) in component styling or globally in `styles.scss`. For more information about theme customization, check the [documentation](https://material.angular.io/guides).

## Helpers

In addition to all the components offered by Angular Material, [various helpers](https://material.angular.io/cdk/categories) are also given such as [drag-and-drop](https://material.angular.io/cdk/drag-drop/overview), [virtual scroll for large lists](https://material.angular.io/cdk/scrolling/overview), [platform information utilities](https://material.angular.io/cdk/platform/overview) and more.

These are easy to use as well, however we will not make an example in this post, but make you aware that they exist.

![drag-drop](https://dev-to-uploads.s3.amazonaws.com/i/fjh8o50yfj6357zj4a3b.gif)

## Design mockup resources

Another cool thing about Material Design is that they offer [many resources and tools](https://material.io/resources) such as design kits for various design tools like Adobe XD, Sketch, Figma and others. I happen to like [Adobe XD](https://www.adobe.com/products/xd.html) which is a user interface design and prototyping tool. 

With the design kit comes components like buttons, input fields and more, and a developer or a UX designer can use the design kit to quickly build user interface mockups for desktop, tablet and phones using the tool.

With an Adobe XD you can define assets, and use them in your design mockups. Adjusting the assets (such as palette colors) will also change your mockups:

![materil-design-adobe-xd](https://dev-to-uploads.s3.amazonaws.com/i/wbcdu0u47671lwyg13ip.PNG)

Material Design also offers other resources and tools for theme palette picking, color tools, shapes, animation and much more.

## Summary

To summarize, Angular Material is easy to install and setup. It offers a wide variety of customizable components and styling. Using Angular Material theming we can customize colors, typography and shapes of our components. We showed how you can make your own theme light or dark. Making changes to the theme also updates all components using the theme. Additionally, Angular Material offers helpers for many common actions such as re-ordering lists. Material Design also offers resources and tools for designing mockups that utilizes Material Design directly in your favorite design tool such as Adobe XD.

## Links and resources:
- [The Angular Framework](https://angular.io/)
- [Angular Material](https://material.angular.io/)
- [The Material Design Specification](https://material.io/)
- [Overview of Angar Material components](https://material.angular.io/components/categories)
- [Material Design Resources](https://material.io/resources)
- [An awesome guide on CSS FlexBox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
- [ChartJS - an awesome framework for making charts](https://www.chartjs.org/)
- If Material Icons aren't enough for you, then take a look at [Font Awesome](https://fontawesome.com/).
- If Material animations aren't enough for you, then take a look at [AnimeJS](https://animejs.com/).