This tutorial will take you on a quick tour of jQuery.mmenu, a jQuery plugin which helps create extensive website navigation. As we examine it, we'll see how we can use this plugin to build an off-canvas menu from scratch.

For the best description of jQuery.mmenu, we’ll head over to its Github page:

“The best jQuery plugin for app look-alike on- and off-canvas menus with sliding submenus for your website and webapp.

The jQuery.mmenu plugin is highly customizable and comes with many add-ons (e.g. counters and dividers) plus extensions (e.g. effects and page shadows). For those who prefer, it’s available as a Wordpress plugin, and it works well in a wide range of browsers!

To begin with, you’ll have to grab a copy of the library. This can be done by visiting its official page, through a package manager (e.g. Bower), or a CDN (e.g. cdnjs).

Please note that depending on the menu you want to build, different assets might be required. For example, an off-canvas menu requires the jquery.mmenu.css (or its minified version) and jquery.mmenu.js (or its minified version) files. Should you want to modify the default behavior of the menu (e.g. move its position to the right), you’ll also have to include the files which are related to the “off-canvas” add-on. If that seems confusing and you don’t want to worry about which are the required files, go ahead and use the “all” files (i.e. jquery.mmenu.all.css and jquery.mmenu.min.all.js ) into your projects.

In our demo, we’ll import the “all” files via a CDN. The head element of our page will reference the “all” CSS file:

 1  

In the same way, we’ll place the “all” script (and a copy of jQuery) before the closing <body> tag:

 1   2  

So, let’s start building the menu!

## Setting Up the HTML

Let’s begin by understanding the structure of our page. Here’s the corresponding HTML code:

 1 
 2 
 3 
 4 
 5  

Notice that we place all the elements, except for the nav element, within a containing div

We can use a different element as the container, but by doing so we’d then have to inform the plugin about this change via the relevant configuration property (i.e. the offCanvas.pageNodetype property). Additionally, if possible, we should avoid declaring a number of CSS properties for the wrapper element. More specifically, the plugin recommends the following:

“This DIV is best off without a (min-/max-)width and height, padding, border and margin.”

## The Markup

The next step is to take a closer look at the structure of the menu. The relevant HTML code looks like this:

 1  

Here we’ve used some straightforward HTML code to build our menu. Unordered lists, with nested lists and links. The plugin doesn’t expect specific markup; happily, we are able to use any markup we want.

We assign a unique identifier to the menu, which we’ll use later in order to instantiate the plugin. Then last but not least, we hide it until all the styles have been successfully applied. This step is important because, by adding the following CSS code, we prevent a jarring FOUC:

 1 nav {  2  display: none;  3 } 

Now that we’ve prepared our page, it’s time to initialize the menu!

## Firing the Plugin

Before showing how we can fire the plugin, let’s first cache a few of our selectors

 1 var $menu =$('#menu');  2 var $btnMenu =$('.btn-menu');  3 var $img =$('img'); 

Now we initialize it by using the code below:

 1 $menu.mmenu({ // configuration settings here });  We can customize the default appearance and the functionality of our menu through CSS and the available configuration settings. We’ll see some examples of this in a moment. Furthermore, we have the option to open and close the menu either automatically or manually. In our case, we’ll show the menu when the element with the btn-menu class is clicked. To achieve this functionality, we’ll take advantage of the available API. Here’s the required code:  1 var api =$menu.data("mmenu");  2   3 $btnMenu.click(function() {  4  api.open();  5 });  In contrast, we’ll choose to hide the menu automatically. This is the default behavior; triggered when we click on any part of the page, except for the part that belongs to the menu. Before we move on, there’s one more thing that I should mention. If we try to open a submenu by clicking on the target menu item (a element), this item will not be entirely clickable. Specifically, the submenu will open only when we click on the right part of that menu item (see the live example to understand this behavior). To make the entire menu item clickable, we have to add the following line of code:  1 $menu.find( ".mm-next" ).addClass("mm-fullsubopen"); 

## Changing the Off-Canvas Image

In this section, the goal is to show a different navigation icon depending on the state of our menu. The screenshot below visualizes what we want to achieve:

To make that happen, we’ll work with the opening and closing events. You can find the documentation of those events in the page which is related to the "offCanvas" add-on. Here’s the snippet we use to change the icons:

 1 api.bind('opening', function() {  2  $img.attr('src', 'arrows_remove.svg');  3 });  4 api.bind('closing', function() {  5 $img.attr('src', 'arrows_hamburger.svg');  6 }); 

Beyond the events above, there are also a few others to play with (e.g. the opened and closed events) which you might find useful for your own projects.

## Changing the Default Width

In order to change the predefined width of the menu, we can use either CSS or Sass (by modifying the source files). By default, its min-width and max-width property values are equal to 140px and 440px respectively. In our demo, let’s see how we can change the initial max-width property value through CSS. Below are the CSS rules that need to be overridden:

 1 .mm-menu {  2  max-width: 350px;  3 }  4   5 /**  6  * add more vendor prefixes  7  * depending on the browsers you're targeting  8  */  9 10 @media all and (min-width: 550px) {  11  html.mm-opening .mm-slideout {  12  transform: translate(350px, 0);  13  }  14 }  15   16 /**  17  * override this rule  18  * in case you're building a right menu  19  */  20 21 @media all and (min-width: 550px) {  22  html.mm-right.mm-opening .mm-slideout {  23  transform: translate(-350px, 0);  24  }  25 } 

At this point, we’ll continue customizing the appearance of the menu. Again, we’ll edit the Sass source file to modify the styles according to our needs. Take a look at the rules that we’ll override below (for simplicity I have omitted the values of the Sass variables):

 1 .mm-menu {  2  background: darken($main-color, 10%);  3 }  4   5 .mm-listview > li > a {  6  color:$text-color;  7  padding: 20px;  8 }  9 10 .mm-listview > li > a:hover,  11 .mm-listview .mm-next.mm-fullsubopen:hover + a {  12  color: $highlight-color;  13 }  14 15 .mm-listview > li > a:hover span {  16  color:$text-color;  17 }  18 19 .mm-menu .mm-listview > li.mm-selected > a:not(.mm-next) {  20  background: transparent url(arrows_check.svg) no-repeat center right 10px;  21  background-size: 30px 30px;  22  text-decoration: line-through;  23 } 

Now consider the very last rule. Each time we click on a menu item, it receives the mm-selected class, so we can use that selector to style it. But we only want to style the very last item in a selection process, so we’ll point to ones which don’t have the class of mm-next

In a previous section, we saw how we initialize the plugin. Now, let’s extend its behavior and functionality by overriding the default configuration options.

First, we change the title that appears above the main panel.

Next, we include the “counters” and the “off-canvas” add-ons. This last add-on allows us to change the position of the menu relative to the page.

Finally, we add three extensions. Check out the final initialization code below:

 1 \$menu.mmenu({  2  counters: true,  3  navbar: {  4  title: "Menu Content"  5  },  6  extensions: ["pageshadow", "effect-zoom-menu", "effect-zoom-panels"],  7  offCanvas: {  8  position : "right",  9  zposition : "back"  10  }  11 }); 

## Conclusion

In this tutorial, we went through the process of creating an off-canvas menu using the jQuery.mmenu plugin. As a next step, dig into the complete source for our demo on CodePen. Then, I suggest you jump into jQuery.mmenu’s official page and look at the various interactive examples that are available. Show us your examples in the comments!

If you're looking for a quick solution, don't forget that Envato Market has a collection of different CSS or JavaScript menus and navigation widgets. It's a good starting point for ideas and examples.