How to make a Hamburger: A menu for mobile websites

Using media queries is great. Every defined size of the viewport can be matched to a specific stylesheet for example. But most of the so called responsive websites are not getting the maximum out of this great possibility.

In most cases it is a problem where to put the main navigation. It should be big enough to touch but small enough not to compete with the main content.

The solution is pretty easy: Let’s make a hamburger.

hamburger mobile menuA hamburger menu has become the way to display a navigation menu on mobile devices. It has the look & feel like an options menu that can be seen recently in all kind of modern native smartphone apps.

A demo of this menu inside a website template can be viewed here.
The code is also available in a public repository on github.

So let’s start with some markup…

The Markup

First of all, a simple HTML5 markup structure have to be generated.

The hamburger button can be as simple as this:

The rest of the markup needs nothing special, except a container element aurround the whole content. This container will be moved to the right after clicking the Hamburger Button. And another div element that covers the content while the menu is shown to make everything clickable on the right and to close the menu again. A metatag for the viewport should be set to scale the content correctly on mobile devices.
Not to forget to link jQuery an jQuery UI, a stylesheet and a javascript in the head.

A completed markup example can be viewed here

The Stylesheet

At the beginning, horizontal scrolling for the whole page has to be disabled, otherwise the content will be scrollable when it will move to the right out of the viewport.

A typical feature of a mobile website is the fixed header on the top, so the hamurger is clickable all the time. But don’t set a position, so it will be fixed to the top of the page and still be in the container when the container moves to the right.

The hamburger itself can be made easy with CSS3. Just add some gradients and rounded corners like this:

The navigation is fixed to the top left of the viewport and layered in background. So it will appear if the content moves to the right. The width is set to 70% and thats the proportion will also use later in the animation:

A completed stylesheet example with a bit of added color and shadows can be viewed here.

The Javascript Animation

Only two click events have to be defined. One to open the menu and one to close it.

When clicked on, jQuery gets the current static width of the content and sets it static to the content element, because if it moves to the right it should keep its original dimensions and not scale to a tiny container.

Also after clicking the hamburger, show the contentlayer above the content on the right, so this transparent layer above content on the right can be used as a big close button. And the scrolling has to be disabled on mobile devices.

Finally do the animation by setting the left margin to 70%

For closing the menu, fetch the click event on the contentLayer. Unbind the touchmove (enable scrolling) an animate the content back again. After that the width of the content can be set again to its dynamic width and the contentLayer has to be disabled again.

A jQuery example can be viewed here.

A live demo of this menu inside a website template can be viewed here.
The code is also available in a public repository on github.
I hope you found this useful – I’m looking forward to your comments or requests for new articles.

hamburger_opened

hamburger_closed

  1. how do i call it out via a shortcut. I want to edit one file that has the menu (like a php) and add a shortcut to my html so i only have to edit once instead of edit each html page.

     

    i tried this and no luck

    <?php
    include(‘menu.php’);
    ?>

  2. Thank you very much for the great tutorial, Thomas! I have one question though. When the menu is open, the content is still scrollable.  How can I disable it?

    • Hi Michelle,
      on mobile devices the scolling is already disabled. To to that for desktop browsers you can add for example something like this to the javascript
      $( '#contentLayer' ).bind( 'mousewheel DOMMouseScroll', function ( e ) {
      e.preventDefault();
      });

  3. Thank you very much Thomas for providing this menu. One bug I found in your demo. On iPhone 4 and 5, after I press the hamburger menu and the sub-menu slides out, I rotate the phone from portrait view to landscape view, then back to portait view. When I then press the hamburger menu to close the submenu, it  resizes the window to 70% with a gray margin of 30% on the right. Any idea how to correct this?

  4. Hello,

    Thank you for the great tutorial. How would a person go about reversing the direction of the content when it slides out of the way? I want to put the hamburger on the right side and make the content slide to the left to reveal the menu which would be on the right. Any help would be greatly appreciated!

    • Hi Andrew,
      just change the margin value in the hambruger.js. If you negate it the menu will slide to the left, like this

      jQuery(“#container”).animate({“marginLeft”: ["-70%", 'easeOutExpo']}, {
      duration: 700
      });

      Keep in mind, that you have to change all the styles displaying the elements on the left to the right with css.

  5. Hello,

     

    First off thank you for that code it works wonderfully. I did discover a bug that I’m not sure how to handle. If your content is too long, and you scroll down far enough and then open the side menu, it will open but not close. If your content is short enough or if you don’t scroll down too far on long content, it will work normally. Any assistance in this matter is greatly appreciated.

    • Hi Brendon,
      do you have a link or something that I can see your implementation? It’s a bit difficult to estimate how long is “too long” :-)

  6. Hey Chris,
    I think this will be much simpler. I would just position the menu absolute on the left side so that it’s outside the viewport. After clicking I would do the same animation with jQuery.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">