DEV Community

Cover image for Build beautiful websites with Angular and Material Design
Peter Øvergård Clausen for IT Minds

Posted on

Build beautiful websites with Angular and Material Design

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 and Angular Material 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 such as the design kits that comes for eg. Adobe XD for effectively designing mockups and prototyping, as well as mention common used helpers that comes with Angular Material.

Angular 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 is a design framework also developed by Google, which contains guidelines, components and tools that support best practices of user interface design.

Angular Material is an implementation of Material Design for Angular. It features many plug-and-play components and styling 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

You may choose to follow along yourself or look at the final code here.

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 is another implementation of Material Design made for React. Material Design is also available for Android, iOS, Flutter and as CDN, but today we'll only be looking at Angular Material.

Let's dive in! 🏊

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:

# 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
Enter fullscreen mode Exit fullscreen mode

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

Step 3 - Add Angular Material:

ng add @angular/material
Enter fullscreen mode Exit fullscreen mode

Angular Material comes with the Indigo/Pink theme by default which is the one you're seeing on the Angular Material homepage. 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.

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:

ng generate component login
Enter fullscreen mode Exit fullscreen mode

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:

<router-outlet></router-outlet>
Enter fullscreen mode Exit fullscreen mode

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:

const routes: Routes = [
  { path: 'login', component: LoginComponent }
];
...
Enter fullscreen mode Exit fullscreen mode

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

Adding a raised Material button

To add a Material button we consult the Angular Material documentation on buttons. Under the API tab it says we need to add the MatButtonModule. And we'll do that in app.module.ts:

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

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
    MatButtonModule
  ],
  ...
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

Then we can add a button to our login.component.html like so:

<button mat-raised-button color="primary" (click)="onButtonClick()">Click me!</button>
Enter fullscreen mode Exit fullscreen mode

And a button handler in login.component.ts like so:

export class LoginComponent implements OnInit {
  ...
  onButtonClick(){
    console.log("Clicked");
  }
}
Enter fullscreen mode Exit fullscreen mode

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

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.

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:

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

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
    MatInputModule,
    MatFormFieldModule
  ],
  ...
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

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

<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>
Enter fullscreen mode Exit fullscreen mode

I also added username and password variables to login.component.ts:

...
export class LoginComponent implements OnInit {
  ...
  username = "";
  password = "";
  ...
}
Enter fullscreen mode Exit fullscreen mode

And using flexbox in login.component.scss to center our content on the page, as well as put the contents in a column order:

// 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;
    }
}
Enter fullscreen mode Exit fullscreen mode

The result can be seen below:

login

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 🎨

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:

@import '~@angular/material/theming';

$primary-palette: mat-palette($mat-indigo);
...
Enter fullscreen mode Exit fullscreen mode

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:

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

h1{
    color: mat-color($primary-palette);
}
Enter fullscreen mode Exit fullscreen mode

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

Making our own theme - Enter dark theme 😎

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:

$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,
  )
);
Enter fullscreen mode Exit fullscreen mode

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:

@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);
...
Enter fullscreen mode Exit fullscreen mode

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:

<body class="mat-typography mat-app-background">
  <app-root></app-root>
</body>
Enter fullscreen mode Exit fullscreen mode

And voila! Dark theme:

dark-theme

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, 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.

Helpers

In addition to all the components offered by Angular Material, various helpers are also given such as drag-and-drop, virtual scroll for large lists, platform information utilities 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

Design mockup resources

Another cool thing about Material Design is that they offer many resources and tools such as design kits for various design tools like Adobe XD, Sketch, Figma and others. I happen to like Adobe XD 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

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:

Top comments (3)

Collapse
 
kr4idle profile image
Pete Steven

Great tutorial.

You can use Desech Studio to import your adobexd design file and then you can integrate with material design and angular.

Here are the github repos for the angular plugin and the material design plugin

Collapse
 
peteroeclausen profile image
Peter Øvergård Clausen

Thank you!

And thank you for the tip! :-)

Collapse
 
mathan26 profile image
mathan26

Great.
I have one question, is flex box enough to Layout and adjust the elements, I often find difficulties in Layout and customization of the components