Reputation: 1944
I'm trying to create a navigation bar using Angular material 2 that collapses in small screens like mobile devices and tablets.
I was only able to find md-button
but not md-menu-bar
as was in Angular material.
Upvotes: 37
Views: 84255
Reputation: 11838
The simplest way to create a responsive navbar with Material is use the Angular CLI schematics.
(If you get 'Collection "@angular/material" cannot be resolved' when running ng add @angular/material, see this)
Then use the generated component <app-my-nav></app-my-nav>
Add the above tag to your main component
Responsive view on Desktop PC:
Responsive collapsed menu with low resolution:
This was seen originally on Angular's blog.
Upvotes: 17
Reputation: 2294
Here is what I used to build my responsive nav-bar
using Angular2+ Material 2 and flex-layout in angular-cli
app.
(Please visit Install Angular Material and Angular CDK)
1) Install flex-layout
npm install @angular/flex-layout -save
2) Include flex-layout in your app.module.ts
import {FlexLayoutModule} from "@angular/flex-layout";
3) Import
imports: [
BrowserModule,
FormsModule,
HttpModule,
RoutingModule,
FlexLayoutModule,
MyOwnCustomMaterialModule // Please visit the link above "Install Angular Material and Angular CDK", and check (Step 3: Import the component modules).
],
app.component.html
<mat-toolbar color="primary">
<button mat-button routerLink="/">
<mat-icon>home</mat-icon>
{{title}}</button>
<!-- This fills the remaining space of the current row -->
<span class="fill-remaining-space"></span>
<div fxLayout="row" fxShow="false" fxShow.gt-sm>
<button mat-button routerLink="/products">Products</button>
<button mat-button routerLink="/dashboard">Dashboard</button>
</div>
<button mat-button [mat-menu-trigger-for]="menu" fxHide="false" fxHide.gt-sm>
<mat-icon>menu</mat-icon>
</button>
</mat-toolbar>
<mat-menu x-position="before" #menu="matMenu">
<button mat-menu-item routerLink="/products">Products</button>
<button mat-menu-item routerLink="/dashboard">Dashboard</button>
<!--<button mat-menu-item>Help</button>-->
</mat-menu>
app.component.css
.fill-remaining-space {
/*This fills the remaining space, by using flexbox.
Every toolbar row uses a flexbox row layout. */
flex: 1 1 auto;
}
Note: to test, resize your page.
take a look at flex-layout docs
Upvotes: 55
Reputation: 1947
Here is my favorite way of creating a responsive Navigation Bar in Angular. If you use Angular 6, make sure you use a version 6.1+
Working example on Stackblitz: https://stackblitz.com/edit/angular-v6xwte
Here are precise steps how to do it:
1) Install necessary packages. Type in your terminal:
npm install --save @angular/material @angular/cdk @angular/animations
npm install @angular/flex-layout --save
2) Import necessary modules in your app.module.ts
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FlexLayoutModule } from '@angular/flex-layout';
import {
MatIconModule, MatButtonModule, MatSidenavModule, MatToolbarModule
} from '@angular/material';
Remember to add these modules to the imports array below.
3) Add Material Icons link to your index.html
The link must go before any Angular content.
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
4) In your styles.css add an Angular theme and set margins to 0%
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
body{
margin: 0%;
}
5) Add toolbar HTML code in your app.component.html
<div style="height: 100vh;">
<mat-toolbar color="primary">
<div fxShow="true" fxHide.gt-sm="true">
<button mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon>
</button>
</div>
<a mat-button class="companyName" routerLink="/">
<span>Site name</span>
</a>
<span class="example-spacer"></span>
<div fxShow="true" fxHide.lt-md="true">
<a mat-button routerLink="/about-us">About us</a>
<a mat-button routerLink="/prices">Prices</a>
<a mat-button routerLink="/start-page">Start page</a>
<a mat-button routerLink="/offer">Offer</a>
<a mat-button routerLink="/contact">Contact</a>
</div>
</mat-toolbar>
<mat-sidenav-container fxFlexFill class="example-container">
<mat-sidenav color="primary" #sidenav fxLayout="column" mode="over" opened="false" fxHide.gt-sm="true">
<div fxLayout="column">
<a mat-button routerLink="/about-us">About us</a>
<a mat-button routerLink="/prices">Prices</a>
<a mat-button routerLink="/start-page">Start page</a>
<a mat-button routerLink="/offer">Offer</a>
<a mat-button routerLink="/contact">Contact</a>
</div>
</mat-sidenav>
<mat-sidenav-content fxFlexFill>
Awesome content
</mat-sidenav-content>
</mat-sidenav-container>
</div>
6) Style the toolbar in your app.component.css
.companyName{
font-size: 150%;
}
div {
overflow: inherit;
}
a{
text-decoration: none;
font-size: 110%;
white-space: normal;
}
button{
font-size: 110%;
min-width: min-content;
}
.example-icon {
padding: 0 14px;
}
.example-spacer {
flex: 1 1 auto;
}
.mat-sidenav-content{
font-size: 200%;
text-align: center;
}
Upvotes: 18
Reputation: 5894
My presentation, Create Enterprise UIs That Your Users Will Love, covers some of these patterns for Angular Material. The links to the StackBlitz examples are in the speaker notes.
Responsive Button Bar with an Overflow menu: This could be placed in or under the TopNav. https://stackblitz.com/edit/material-responsive-button-bar?file=app%2Fbutton-bar%2Fbutton-bar.component.ts
Dynamic Nested TopNav Menu: Note that this menu is not fully accessible. More work is needed to fully support a good a11y experience. https://stackblitz.com/edit/dynamic-nested-topnav-menu?file=app/app.component.ts
Dynamic Nested SideNav Menu: If you use the Transform Pattern to switch your TopNav to a SideNav on mobile, this shows how to build a dynamic SideNav menu. https://stackblitz.com/edit/dynamic-nested-sidenav-menu?file=app%2Fapp.component.html
Upvotes: 3
Reputation: 123
I have edited user2662006's answer with some fixes and code optimizations below. Note that my StackOverflow points are currently too low to even grant me the privilege to submit a comment let alone editing.
1) Install Angular Material and Angular CDK
2) Install flex-layout
npm install @angular/flex-layout -save
3) Include flex-layout in your app.module.ts
import {FlexLayoutModule} from "@angular/flex-layout";
4) Import related material and flex modules
imports: [
...,
FlexLayoutModule,
MatToolbarModule,
MatIconModule,
MatMenuModule,
MatButtonModule,
],
app.component.html
<mat-toolbar color="primary">
<button mat-button routerLink="/">
<mat-icon>home</mat-icon>
{{title}}
</button>
<span class="fill-remaining-space"></span>
<div fxLayout="row" fxHide fxShow.gt-sm>
<button mat-button routerLink="/products">Products</button>
<button mat-button routerLink="/dashboard">Dashboard</button>
</div>
<button mat-button [mat-menu-trigger-for]="menu" fxShow fxHide.gt-sm>
<mat-icon>menu</mat-icon>
</button>
</mat-toolbar>
<mat-menu x-position="before" #menu>
<button mat-menu-item routerLink="/products">Products</button>
<button mat-menu-item routerLink="/dashboard">Dashboard</button>
</mat-menu>
app.component.css
.fill-remaining-space {
/*This fills the remaining space, by using flexbox.
Every toolbar row uses a flexbox row layout. */
flex: 1 1 auto;
}
Notes:
Upvotes: 4
Reputation: 3156
You can build a responsive menu by using mat-toolbar
, mat-sidenav
and flex-layout
(fxFlexFill
, ...).
Upvotes: 2
Reputation: 618
My crude attempt to modify the answer with a toolbar with drawer implementation with new component names as of angular-material 5.0.2
To do: Need to get CSS of all header links fixed. Menu icon should be transparent.
https://responsivematerial2.stackblitz.io/
.mat-sidenav-container {
background: rgba(0, 0, 0, 0.08);
}
.blank-grow {
flex: 1 1 auto;
}
<mat-sidenav-container fullscreen>
<mat-sidenav #sidenav>
<mat-nav-list>
<a mat-list-item>
<mat-icon mat-list-icon>home</mat-icon>
<span mat-line>home</span>
</a>
<a mat-list-item>
<mat-icon mat-list-icon>backup</mat-icon>
<span mat-line>Backup</span>
</a>
</mat-nav-list>
</mat-sidenav>
<mat-toolbar color="primary">
<button mat-icon-button (click)="sidenav.open()" fxHide="false" fxHide.gt-sm>
<mat-icon>menu</mat-icon>
</button>
<span> Big Header</span>
<span class="blank-grow"></span>
<div fxLayout="row" fxShow="false" fxShow.gt-sm>
<a>
<mat-icon mat-list-icon>home</mat-icon>
<span mat-line>home</span>
</a>
<a>
<mat-icon mat-list-icon>backup</mat-icon>
<span mat-line>Backup</span>
</a>
</div>
</mat-toolbar>
</mat-sidenav-container>
Upvotes: 4
Reputation: 305
Have a look at angular2-material
project on github. Here is a list of material design components they have published so far:
https://www.npmjs.com/~angular2-material
Also, I think either md-sidenav
or md-toolbar
is what you are looking for.
md-sidenav
- https://www.npmjs.com/package/@angular2-material/sidenav
md-toolbar
- https://www.npmjs.com/package/@angular2-material/toolbar
Note: The project is still in alpha release which means there can be breaking changes in their API. Not recommended to use in production.
Upvotes: 4