Skip to main content

Our Off-Canvas Menu Plugin

By Matt Gifford

Published on June 7th, 2013

Topics

On a recent responsive design project, we wanted an off-canvas menu for narrow viewports. We tried some of the off-canvas menu libraries out there. But, being very particular about design and performance, we ended up writing our own.

Our library, the not-so-creatively-named offCanvasMenu, is a jQuery/Zepto plugin built for flexibility and performance.

Many of the libraries we tried required that we structure our HTML in a certain way. Others were built to be a complete responsive menu solution, having their own opinions about where the breakpoints should be. We found both of these aspects to be too restrictive.

offCanvasMenu doesn’t depend on the structure of your HTML. Just specify which elements to use for the menu and menu trigger, and the plugin takes care of the rest.

It is not a responsive menu. It’s meant to be used as part of the responsive system you’re already using. Your code determines when to turn it on and off. The plugin also exposes methods for opening and closing the menu, if you wish to add support for other gestures, such as swipe.

offCanvasMenu, when used with Modernizr, will use CSS transforms for animation if the browser supports it. Of course, if the browser doesn’t support CSS transforms, it will fall back to using jQuery/Zepto animation.

It also eliminates the 300 ms delay between a tap and the resulting animation by firing on touchstart and mousedown, rather than click.

Update: We’ve changed our thinking on tap-handling within the plugin and have removed the feature. This is best handled on the page level, using a library like FastClick.

You can see the plugin in action as part of a responsive design on its GitHub page. To see more examples or get the plugin, go to the repository page. Please let us know if you have suggestions for improvement or run into any problems.

We hope you find it useful.

Comments

JF said:

Great Job, good concepts !

Just too bad it doesn’t play well with multiple instance on the same page, but I’ll probably adapt it so it can.

Thanks for sharing !

Paul Frost said:

You mention it’s possible to add support for other gestures, such as swipe.
I really like the method you are using, but I’m thinking of using it with a very long list of navigation options in the menu, which on a phone would be longer than one screenful. I thought it would be nice to have the option to swipe the menu off screen if you had scrolled down and the menu button was no longer visible.
I’ve had a look around the code and on the jQuery website to see if I could solve it myself but my javascript is not up to the task. Can you point me in the right direction or supply an example?

Josh McKenney said:

Any performance tuning for large pages? Do css transforms have a threshold on large pages with lots of content or does the gpu handle the movement in almost every case? Looking at a project where more than a menu is hidden and large pages would be hidden when the new “menu/page” animates in.

Laurelle said:

Hi,

Is there a way to stop the mobile menu from displaying when you first load the page? It displays for about a second and then disappears. I would like to not have the mobile menu display when the page first loads.

Thank you.

Replies to Laurelle

Tyler Sticka (Cloud Four Team Member) replied:

The menu will not receive any custom styles until the plugin has had a chance to activate. With this in mind, there are a few ways you might prevent it from displaying initially.

The simplest way would be to hide the menu by default using CSS:

.my-menu { display: none; }

…then show it again when the plugin is active:

.off-canvas-menu .my-menu { display: block; }

You could also try reducing the time the JavaScript takes to activate by moving it higher in your source. This may slow down the overall experience, though.

If nothing’s working, you should totally open a GitHub issue with more detail.

Flynn said:

Thank you for sharing this menu! I tried other plugins, but their code was bloated with too many bells and whistles. I love the fact that your code is simple, lightweight and flexible.