Off-canvas Menus in Drupal 7Off-canvas Menus in Drupal 7

One current trend in the world of web design is to limit the display of certain design elements unless specifically called for. This serves to clean up the page design and helps prevent over-cluttering. For certain types of designs this can be a great benefit, for instance, responsive sites or simple landing pages.
Today we're going to be experimenting with moving the menu off-canvas. The "canvas" is the term used to describe the visible browser viewport (the part of the browser that would be visible initially or by scrolling). When we move an element off-canvas, it will not initially be visible to the user. We then provide an intractable element to bring the element into view.
Doing this with menus is typically achieved by using the increasingly popular "hamburger" icon. Note that there is a debate currently happening in the design community over the legitimacy of this icon and whether it is bad usability. I'm not going to debate that here, but just know that it is up to you to decide what kind of icon or text you want to use to trigger the menu.
To save some time, we are going to be implementing the code used on the amazing repository.

Step 1: Setting up the menu in Drupal

There isn't any special process for setting this up, it will work fine with the default system menu. Head to /admin/structure/menu and add menu items as you need.

Step 2: Setting up the template in Drupal
Go to the Codrops article and download the demo files.

The first thing we need to do is migrate all the correct files used in the demo into your site. Navigate to your theme's folder at /sites/all/themes/mythemename/. Create directories called "js" and "css" respectively if you don't already have them. In your "js" directory, place the files found at OffCanvasMenuEffects/js/classie.js and OffCanvasMenuEffects/js/main.js. In your "css" directory, place the files found at OffCanvasMenuEffects/css/demo.css and OffCanvasMenuEffects/css/menu_sideslide.css.
Next we must alter our theme .info file to include these:

stylesheets[all][] = css/demo.css
stylesheets[all][] = css/menu_sideslide.css
scripts[] = js/classie.js
scripts[] = js/main.js


In order to make this code work off the given sample, I created a new page.tpl file with the following setup:

<div class="container">
    <div class="menu-wrap">
        <nav class="menu">
            <!--PRINT YOUR MENU HERE-->
        <button class="close-button" id="close-button">Close Menu</button>
    <button class="menu-button" id="open-button">Open Menu</button>
    <div class="content-wrap">
        <div class="content">
            <!--PRINT YOUR CONTENT HERE--> 


As long as you follow this basic setup, the sample code should work fine. You may want to take this code an tweak it for your own usage if you plan on changing the div names or classes.
I also created a custom region just for my main menu (it makes for easy placement). Because my main menu is within a region, it gets wrapped in a div with class "content" attached to it. This becomes problematic when the menu is activated because it prevents menu items from be intractable. To counteract this I created a custom block--main_menu.tpl file with the contents:

<div id="<?php print $block_html_id; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>
    <?php print $content ?>


Step 3: Implementing the javascript
We are going to have to make some basic modifications to the loaded javascript. Because we defined the JS file in our theme's .info file, Drupal will try to load JS first, then the HTML. This issue that arises is that, since the HTML doesn't exist when the javascript is loaded, the JS will fail to initialize. To fix this we need to wrap the main.js document in a function to check to make sure the DOM is loaded.

window.onload=function() {
    //Sample code is inserted here here


The expected behavior here is then to click on the menu element, the menu will show and a body class will be added. Clicking on the element again or any area outside of the menu will close it again.

Step 4: Implementing the CSS

This is going to be slightly different for everyone. In my case I only needed to make minor adjustments to padding and background colors. One thing to note is that the default behavior of the given code is to place a semi-transparent div directly over any dov with the class "content," which could be problematic for many drupal installations due to the frequent use of that class (it can lead to many overlapping transparent divs which looks weird when the menu is active). The solution there is to either change the sample code class name or to rework your theme around this issue.
One thing you will most likely have to change is the class ".icon-list" in menu_sideslide.css. Since I used the default Drupal menu system, I had to replace all instances of that class with ".menu" instead, then everything worked as planned.
Hopefully this gives you some ideas of how to implement off-canvas menus in your next project.


Need a Custom Designed Theme?

If you need a custom designed theme for your business then our designers can work with you to create a unique concept that is consistent with your brand, clearly communicates your value proposition and helps you achieve your goals. >> Click here to contact us and let us know about your needs and we'll analyze and provide you with an estimate for designing and development your custom theme.