Responsive Navbar with Angular Flex Layout

Today, we are going to create a responsive Navbar using Toolbar and Sidenav Components from Angular Material together with Angular Flex Layout. We will be trying to replicate the behavior of Navbar in where it collapses on small screen and is fully displayed in Large screen.

Responsive Navbar with Angular Material and Angular Flex Layout

View on Larger Screens

Responsive Navbar with Angular Material and Angular Flex Layout

View on Small Devices

If you are not aware, Angular Flex Layout provides a responsive Layout API with CSS flexbox and media query for Angular application. This post assumes you have knowledge in Angular 2+ applications and will not cover the basics. If you are new to Angular, you can learn how to get started here.

Let’s get started:

Installation and Initial Setup

Angular Material

To install and setup Angular Material, you can follow the detailed instruction here from the official guide.

Angular Flex Layout

Installing Angular flex layout is simple. Use the following commands:

NPM

npm install @angular/flex-layout –save

Yarn

yarn add @angular/flex-layout

Then import the Flex Layout Module in your app.module.ts as show below

import { FlexLayoutModule } from "@angular/flex-layout";

Don’t forget to include FlexLayoutModule in the list of imports in ngModule imports.

Assuming you have successfully installed and setup both Angular Material and Angular Flex Layout, let’s move on and create a responsive navigation bar.

Creating a Toolbar and a Sidenav

This is rather a straightforward process. We will create a toolbar at the top of the window and a side navigation bar with the same content as the toolbar. The toolbar will have a menu item that will open the Sidenav. This item will only be shown on small screen when the rest of the menu is hidden and vice versa.

To create a toolbar, you use the following code below.

<mat-toolbar color="primary">

  <span>Responsive Navigation</span>

  <span class="example-spacer"></span>

  <a href="#" mat-button>Menu Item 1</a>

  <a href="#" mat-button>Menu Item 2</a>

  <a href="#" mat-button>Menu Item 3</a>

  <a href="#" mat-button>Menu Item 4</a>

  <a href="#" mat-button>Menu Item 5</a>

  <a href="#" mat-button>Menu Item 6</a>

</mat-toolbar>

As you see, this is Just a normal material toolbar without any responsive capabilities. Next, lets create a Sidenav with the same items.

  <mat-sidenav-container fxFlexFill class="example-container">

    <mat-sidenav fxLayout="column" mode="side" opened="false">

      <div fxLayout="column">

        <a href="#" mat-button>Menu Item 1</a>

        <a href="#" mat-button>Menu Item 2</a>

        <a href="#" mat-button>Menu Item 3</a>

        <a href="#" mat-button>Menu Item 4</a>

        <a href="#" mat-button>Menu Item 5</a>

        <a href="#" mat-button>Menu Item 6</a>

      </div>

    </mat-sidenav>

    <mat-sidenav-content fxFlexFill>Main content</mat-sidenav-content>

  </mat-sidenav-container>

Now that we have both a Sidenav and a toolbar working, let's work on making them responsive.

Adding Responsiveness using Angular Flex Layout

To add responsiveness to our navbar, we will use Angular Flex Layout to hide and show the toolbar menu items based on screen size. To do this, we enclose the menu items on a div container and then use fxHide and fxShow directive to hide and show the menu items.

Example:

To hide some content on small screens only:

<div fxFlex fxShow=”true” fxHide.sm=”true” ></div>

To hide some content on both small and extra small screens only:

<div fxFlex fxShow=”true” fxHide.lt-md=”true”></div>

Simple? Now, let’s add this to our menu item:

<div style="height: 100vh;">

  <mat-toolbar color="primary">

    <span>Responsive Navigation</span>

    <span class="example-spacer"></span>

    <div fxShow="true" fxHide.lt-md="true">

      <!-- The following menu items will be hidden on both SM and XS screen sizes -->

      <a href="#" mat-button>Menu Item 1</a>

      <a href="#" mat-button>Menu Item 2</a>

      <a href="#" mat-button>Menu Item 3</a>

      <a href="#" mat-button>Menu Item 4</a>

      <a href="#" mat-button>Menu Item 5</a>

      <a href="#" mat-button>Menu Item 6</a>

    </div>

  </mat-toolbar>

Now, if you resize the browser width to small size, the menu items are hidden instead of being squeezed. But, we need to show a menu icon to reveal or draw the Sidenav on small screens. This will work similarly to the above code but have the opposite effect: Show on small screen, hide on large screens.

<div fxShow="true" fxHide.gt-sm="true">
      <a href="#">Show Side Menu</a>
</div>

As you can see, instead of hiding on lt-md (less than medium screen size) we are showing the single menu item on gt-sm(great than small screen size). You can use the table below for various breaking points of Angular Flex Layout Responsive API.

Now let’s add the code on the “Show Side Menu” menu item so that it reveals the Sidenav menu items.

<div fxShow="true" fxHide.gt-sm="true">
     <a href="#" (click)="sidenav.toggle()">Show Side Menu</a>
</div>

Final Code

The whole code for a responsive navbar menu will look like this:

<div style="height: 100vh;">

  <mat-toolbar color="primary">

    <span>Responsive Navigation</span>

    <span class="example-spacer"></span>

    <div fxShow="true" fxHide.lt-md="true">

      <!-- The following menu items will be hidden on both SM and XS screen sizes -->

      <a href="#" mat-button>Menu Item 1</a>

      <a href="#" mat-button>Menu Item 2</a>

      <a href="#" mat-button>Menu Item 3</a>

      <a href="#" mat-button>Menu Item 4</a>

      <a href="#" mat-button>Menu Item 5</a>

      <a href="#" mat-button>Menu Item 6</a>

    </div>

    <div fxShow="true" fxHide.gt-sm="true">

      <a href="#" (click)="sidenav.toggle()">Show Side Menu</a>

    </div>

  </mat-toolbar>

  <mat-sidenav-container fxFlexFill class="example-container">

    <mat-sidenav #sidenav fxLayout="column">

      <div fxLayout="column">

        <a (click)="sidenav.toggle()" href="#" mat-button>Close</a>

        <a href="#" mat-button>Menu Item 1</a>

        <a href="#" mat-button>Menu Item 2</a>

        <a href="#" mat-button>Menu Item 3</a>

        <a href="#" mat-button>Menu Item 4</a>

        <a href="#" mat-button>Menu Item 5</a>

        <a href="#" mat-button>Menu Item 6</a>

      </div>

    </mat-sidenav>

    <mat-sidenav-content fxFlexFill>Main content</mat-sidenav-content>

  </mat-sidenav-container>

</div>

You can get the whole project on github.

Conclusion

This is a simple example of how you can use Angular Material and Angular Flex Layout to create a nice responsive navigation bar for your own application. If you have any question regarding anything I covered in this article, feel free to raise it in the comment section below and I will get back to you. You can also make suggestion on how to improve this simple navbar and other topics you would like me to cover.

21 Replies to “Responsive Navbar with Angular Flex Layout”

  1. Hi, Would be great if anyone could help. I’ve managed to get the above working (Very easy!). But i have a small issue, i’ve created the toolbar in a component that a call from the App.compnent via routing. The issue i have main body content is not being displayed due to the fact that the Style “Height:100vh” is covering the entire screen. Is there a way of systematically increasing and decreasing the size.? Thanks

    1. Without seeing your code so i can see the issue myself, i may not be able to help you a lot. But to increase and reduce height, you try and subscribe to MediaChange under Angular Flex Layout for Adaptive Layout. However, I have never tried that with height only with width.

  2. how to would i change this, so it adds only one item at a time from the menu bar at a time as you shrink the windows?

  3. Hi Maina, I’m back, and I have made a website based on the navigation that you demonstrated. My question concerns the element

    I have noticed that if you resize the browser, or change the height of the mat-toolbar, you need a different value. 100vh is always too much, unless I go to a very big window. Do you know of a way to perhaps control this value, or if there is another way to set the value to 100% of the window size, no more, no less?

    1. The .close and .open functions have been deprecated since i made this article. You can now use .toggle function in the place. I have updated the article accordingly, Thanks.

  4. Just a simple question. I am actually learning Angular and Material with Flex-Layout, and I was wondering : is this the good way of doing responsive things ? I first learnt Bootstrap, and when I see this it seems .. “clunky”, just because we have to set up two containers for navigation.

    Of course, when I found your article I thought “Oh that’s what I was thinking to do to solve my problem” but it feels like I am doing patchwork.

    Also, is Material good for responsiveness ? Or should we use it on desktop-first approach ? Thank you very much for your time and answers, nice article !

    1. To put it simply, Both Angular Flex Layout and Bootstrap test your skill as a designer. Angular Flex Layout, give you more control over your responsive as compared to bootstrap but Bootstrap is no slouch either.

      Angular Flex Layout is extremely effective especially when you combine its responsive layout capabilities with its adaptive layout capabilities. About angular material, it doesn’t provide responsive on it’s own but relies with either Angular Flex or even Bootstrap or just css. It strives to provide a nice interactive User Experience while bootstrap strives to provide a simple clean UI.

      On whether to take the desktop first approach or mobile first approach, it’s all up to you. Sometimes responsives design comes out nicely and sometimes it doesn’t. Take a look at Adaptive layout design and combine it with responsive design for the best approach.

  5. This was a great intro and produces pretty much the framework i needed. The only thing that I would want on top of this is a toolbar that shrinks down to a fixed size as you scroll the mat-sidenav-content. Would you be able to give me a couple of pointers on how that night be done? thanks, and thanks for the post.

      1. Yes Maina, that’s close enough, if I can use a scroll event or something like that to detach and hold the toolbar, then I have all the tools I need to also compact it, if I want. The problem is that I want to be able to scroll for a bit without change, but after a certain point the menu should become compact and stay in place. Check this site out: https://www.havealook.com.au/

        They seem to do it quite nicely.

  6. It should be “npm install @angular/flex-layout –save” instead of “npm install @angular/flex –save”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.