Exploring Material 3 Design With Angular Material

In this article, we will explore Material 3 design integration with Angular Material.

26th April, 2024 — 6 min read

Open in StackBlitz
Angular Material team is soon going to roll out the stable usage of it's Material 3 (M3) integration. This integration is already part of it's `next` major release. In this article, we are going to use the yet to be released `18` (or `next`) version of Angular, Angular CLI and Angular Material. The goal of this article is to give a quick idea about what is coming up with Angular Material in it's next major release. ## Creating a `v18` Angular Project ```bash npx @angular/cli@next new angular-material-3 ``` Then select `Sass (SCSS)` for styling and `No` for `SSR/SSG/Prerendering`. ```bash ? Which stylesheet format would you like to use? Sass (SCSS) [ https://sass-lang.com/documentation/syntax#scss ] ? Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)? No ``` And lastly, move into the project folder: ```bash cd angular-material-3 ``` ## Adding Angular Material `v18` Let's add `@angular/material` into the newly created project: ```bash ng add @angular/material@next ``` And select answers as below: ```bash ? Choose a prebuilt theme name, or "custom" for a custom theme: Custom ? Set up global Angular Material typography styles? Yes ? Include the Angular animations module? Include and enable animations ``` ### New M3 Themes When selecting the theme, notice that now we are getting options of new themes: | Theme Name | | ---------------- | | Rose & Red | | Azure & Blue | | Magenta & Violet | | Cyan & Orange | These are new themes created by Angular Material team to be compatible to M3. If you have selected **Custom**, your `styles.scss` would look like below: ```scss @use "@angular/material" as mat; @include mat.core(); $angular-material-3-theme: mat.define-theme( ( color: ( theme-type: light, primary: mat.$azure-palette, tertiary: mat.$blue-palette, ), density: ( scale: 0, ), ) ); :root { @include mat.all-component-themes($angular-material-3-theme); } ``` The syntax is almost similar to what it was in Material 2 (M2) integration with Angular Material. But, notice the usage of new palettes. We are using `$azure-palette` and `$blue-palette`. Below are all new palettes introduced in M3 integration with Angular Material, that can be used with the `primary` and `tertiary` options: - `$red-palette` - `$green-palette` - `$blue-palette` - `$yellow-palette` - `$cyan-palette` - `$magenta-palette` - `$orange-palette` - `$chartreuse-palette` - `$azure-palette` - `$violet-palette` - `$rose-palette` ## Creating basic app Let's create a simple application to see and understand basic usages of updated `SASS` `mixins` for M3 in Angular Material. We are going to use [Angular Material Schematics](https://material.angular.io/guide/schematics) to generate components: ```bash ng generate @angular/material:navigation layout ng generate @angular/material:dashboard dashboard ng generate @angular/material:address-form address-form ng generate @angular/material:table table ng generate @angular/material:tree tree ng generate @angular/cdk:drag-drop drag-drop ``` ### Updating layout Go to `src/app/layout/layout.component.html` and add `` in `` like below: ```angular-html
``` Next, let's add and modify some styling in `src/app/layout/layout.component.scss` so that sidenav content looks more M3 oriented: ```scss .sidenav-container { height: 100%; } .sidenav { width: 240px; padding: 0 8px; box-sizing: border-box; } .mat-toolbar.mat-primary { position: sticky; top: 0; z-index: 1; } mat-sidenav-content { padding-right: 16px; } .sidenav-scroll-wrapper { height: calc(100dvh - 64px - 16px); overflow: auto; border-radius: 16px; box-sizing: border-box; } .sidenav-content { max-height: 100%; overflow-y: auto; padding: 16px; box-sizing: border-box; @media (pointer: fine) { &::-webkit-scrollbar { background-color: transparent; width: 8px; } &::-webkit-scrollbar-thumb { border-radius: 4px; } } } @media (max-width: 959.98px) { mat-sidenav-content { padding-right: 8px; padding-left: 8px; } .sidenav-scroll-wrapper { height: calc(100dvh - 64px); } .sidenav-content { overflow-y: visible; padding: 8px; } } ``` ### Using layout Now, simply go to `src/app/app.component.html` and update it's content with below: ```angular-html ``` Also, don't forget to import `LayoutComponent` in `src/app/app.component.ts`. At this point, the output looks like below: ![output after updating layout](/assets/angular-material.dev/Exploring%20Material%203%20With%20Angular%20Components/updating%20layout.jpg) Let's add some colors in the content area so that it's easy to distinguish. ### Theming layout Create a file `src/app/layout/_layout-component.theme.scss` with below content: ```scss @use "@angular/material" as mat; @mixin theme($theme) { .sidenav-scroll-wrapper { background-color: rgba(mat.get-theme-color($theme, primary-container), 0.75); } .sidenav-content { @media (pointer: fine) { &::-webkit-scrollbar-thumb { background-color: mat.get-theme-color($theme, primary); } } } } ``` Notice the usages of `get-theme-color` mixin: 1. To get color of the `primary-container` role, we used `mat.get-theme-color($theme, primary-container)` 2. To get color from tonal palette, we used `mat.get-theme-color($theme, primary)`. To learn more, checkout [Reading tonal palette colors](https://material.angular.io/guide/material-3#reading-tonal-palette-colors) and [Reading color roles](https://material.angular.io/guide/material-3#reading-color-roles). ### Using layout component theme Now, include and call this mixin in main `styles.scss` file: ```scss @use "./app/layout/layout-component.theme"; :root { @include layout-component.theme($theme); } ``` Let's see the output now: ![output after layout theming](/assets/angular-material.dev/Exploring%20Material%203%20With%20Angular%20Components/layout%20theming.jpg) ### Updating routes Go to your `src/app/app.routes.ts` and update the routes: ```angular-ts import { Routes } from '@angular/router'; export const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'dashboard', }, { path: 'dashboard', loadComponent: () => import('./dashboard/dashboard.component').then( (c) => c.DashboardComponent ), title: 'Dashboard' }, { path: 'address', loadComponent: () => import('./address-form/address-form.component').then( (c) => c.AddressFormComponent ), title: 'Address' }, { path: 'table', loadComponent: () => import('./table/table.component').then( (c) => c.TableComponent ), title: 'Table' }, { path: 'tree', loadComponent: () => import('./tree/tree.component').then( (c) => c.TreeComponent ), title: 'Tree' }, { path: 'drag-drop', loadComponent: () => import('./drag-drop/drag-drop.component').then( (c) => c.DragDropComponent ), title: 'Drag-Drop' }, ]; ``` And to load the routes, we will first update `src/app/layout/layout.component.ts`: ```angular-ts import { RouterLink, RouterLinkActive } from '@angular/router'; @Component({ selector: 'app-layout', // rest remains same imports: [ // Add below imports RouterLink, RouterLinkActive ] }) export class LayoutComponent { rootRoutes = routes.filter(r=>r.path); // rest remains same } ``` Now, replace `` content with below: ```angular-html @for (item of rootRoutes; track $index) { {{ item.title }} } ``` At this point the output looks like below: ![embedded video](/assets/angular-material.dev/Exploring%20Material%203%20With%20Angular%20Components/updating%20routes.mp4) ## Custom M3 theme We saw in the beginning that Angular Material team provides some pre-built palettes and themes. But, it is also possible to generate a theme based on a custom color. To do so, simply run below command: ```bash ng generate @angular/material:m3-theme ``` After running the above script, your will be presented some questions, answer them like below: | Question | Answer | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | | What HEX color should be used to generate the M3 theme? It will represent your primary color palette. (ex. #ffffff) | **`#6750A4`** | | What HEX color should be used represent the secondary color palette? (Leave blank to use generated colors from Material) | *Leave blank* | | What HEX color should be used represent the tertiary color palette? (Leave blank to use generated colors from Material) | *Leave blank* | | What HEX color should be used represent the neutral color palette? (Leave blank to use generated colors from Material) | *Leave blank* | | What is the directory you want to place the generated theme file in? (Enter the relative path such as 'src/app/styles/' or leave blank to generate at your project root) | *Leave blank* | | Do you want to use system-level variables in the theme? System-level variables make dynamic theming easier through CSS custom properties, but increase the bundle size. | **`No`** | | Choose light, dark, or both to generate the corresponding themes | **`both`** | The schematic will create a file called `m3-theme.scss` at root. You can explore the file to understand how the theme is created: ```scss // m3-theme.scss - content reduced for brevity $light-theme: mat.define-theme(( color: ( theme-type: light, primary: $_primary, tertiary: $_tertiary, ) )); $dark-theme: mat.define-theme(( color: ( theme-type: dark, primary: $_primary, tertiary: $_tertiary, ) )); ``` Now, you can simply use these newly created themes in main `styles.scss`: ```scss @use "../m3-theme"; :root { @include mat.all-component-themes(m3-theme.$light-theme); } ``` And the output will look like below: ![embedded video](/assets/angular-material.dev/Exploring%20Material%203%20With%20Angular%20Components/custom%20m3%20theme.mp4) ## Conclusion We created a `v18` Angular application. And installed `@angular/material`'s `next` (`v18`) version in it. Then we created some boilerplate components like dashboard, address-form, tree, table and drag-drop views using [Angular Material Schematics](https://material.angular.io/guide/schematics). After creating components, we modified layout component and it's styling, and we started using it in main app component. Lastly, we learned the usage of new schematic `ng generate @angular/material:m3-theme`. The code is available on [GitHub](https://github.com/Angular-Material-Dev/angular-material-3). ## Live Playground ## New Course Announcement This article was written when Material 3 was not yet stable with Angular Material. But, with Angular Material 18, support for Material 3 is stable! If you want to learn more about Angular Material for Material 3 design, I have introduced a new course, feel free to check it out! [![Angular Material 3 Theming System: Complete Guide](/assets/courses/m3-ng-components/img/cover.jpg "Angular Material 3 Theming System: Complete Guide")](/courses/overview/m3-ng-components)
Dharmen Shah
Written by Dharmen Shah

I have around 8+ years of experience in IT industry. I have got opportunity to work at different companies with different technologies, mostly focused on Front-end, like Angular, React, Next, vanilla web stack (HTML, CSS, JavaScript).

You can find me on Twitter, Linkedin and Github.

Discuss online

Share this article

Read more

View all articles

Learn more

View courses page

Envelop
Don't miss any update

Stay up to date

Subscribe to the newsletter to stay up to date with articles, courses and much more!

Angular Material Dev

Angular Material Dev is one place stop for developers to learn about integrating Material Design in Angular applications like a pro.

Find us on X (Twitter) and LinkedIn