Building a delicious “hamburger” button app layout

In the previous post, Designing a delicious “hamburger” button app layout, we walked through, why apps use the hamburger layout style and some design elements that make up a good implementation.

In this post, we’ll walk through how to build a great implementation in HTML and JavaScript, targeting Windows Phone and Windows 8. We’ll work to build something that has all of the ingredients of a good hamburger button app, and of course we’ll share the code!

Setup the viewport

First of all, we want to build a layout that accommodates up to three scrolling panels. The main content div in the center, and the secondary left-menu and right-menu divs on either side.  We put all of the panes in a surface div that will scroll left to right, and we wrap that with a viewport, that will be the outer scrolling div.

<div class="viewport">
    <div class="surface">
       <div class="content"></div>
       <div class="menu-left"></div>
       <div class="menu-right"></div>
    </div>
</div>

 

Sizing the viewport

Next, we’ll make the main content pane width 100% to make it fill the width of the screen, and give the menu panes a fixed with that’s less than the width of the screen, in this case 300px. We make them a smaller than the width of the screen to ensure you can always see the main content pain when you are scrolled over to a menu pane.

We need to explicitly size the width of the scrolling surface div to be bigger than the screen. Then we set up a grid with the sizes of each of our columns, and put the panes into the grid columns.

.viewport {
    width: 100%;
    overflow-x: scroll;
}

.surface {
    width: calc(300px + 100% + 300px);

    display: -ms-grid;
    -ms-grid-columns: 300px 1fr 300px;
    -ms-grid-rows: 1fr;
}

.menu-left {
    -ms-grid-column: 1;
}

.content {
    -ms-grid-column: 2;
}

.menu-right {
    -ms-grid-column: 3;
}

Add mandatory snap points

Snap points are magical. Scrolling is an amazingly complex system behavior, and since  scrolling surfaces are offloaded to the touch and graphics hardware it’s hard to manipulate it’s behavior. Snap points, however, let you change the scroll behavior with a little bit of CSS.

The snap points force touch scrolling to stop where  you set them. All we have to do as add snap points before each of the panes. We want one at the start of the view, one at the start of the content, and a last one that will make it stop at the end.

.viewport { 
    -ms-scroll-snap-type: mandatory; 
    -ms-scroll-snap-points-x: snapList(0%,
                                       300px,
                                       calc(300px + 300px)); 
}

Progress so far

So, after simply setting up a wide three-paned view with snap points inside of a viewport the size of the screen, we can see the basics of our hamburger layout coming together.

Since we built it on top of native scrolling behavior we get the nice buttery, stick to your finger touch interactions for free. Thanks snap points.

Add the hamburger button

Adding the button itself to the header is simple enough, but we want to make sure it behaves correctly and animates smoothly if someone were to click on it. First, we drop in the header with the hamburger button. Easy.

<div class="content">
    <div class="header">
        <button class="hamburger"/>
        <h1>Header</h1>
    </div>
 </div>

Then, we set up a handler that takes you over to the menu pane if you click the hamburger button. We use msZoomTo to programmatically pan between the different panes. MsZoomTo is nicely animated and better performing than simply changing the scroll offset values.

hamburgerButton.addEventListener("click", toggleMenu);

function toggleMenu(e) { 
    var scrollPos = (_viewport.scrollLeft > 0) ? 0 : _menuWidth; 
    _viewport.msZoomTo({ contentX: scrollPos }); 
}

Sweet. Now we have a working button, that works nicely in concert with the touch panning behavior.

We also want to make sure that when you are looking at a menu, if you click on the content area it will take you back. We’ll implement it just like the button.

content.addEventListener("click", returnToContent);
function returnToContent(e) { 
    if (_viewport.scrollLeft < _menuWidth || 
         _viewport.scrollLeft >= _menuWidth * 2) {

        _viewport.msZoomTo({ contentX: _menuWidth }); 
    }
}

Initial scroll position

When the launch the app, it will show the menu, which is probably not desired. Let’s start with the scroll position past the menu when you launch the app.

_viewport.scrollLeft = _menuWidth;

Hide the panning indicator

panning

You may have noticed panning indicator at the bottom of the view as you pan between the different menus. This makes sense to see when you’re panning through content, but when you’re panning between different parts of the app, it doesn’t really make sense and can be distracting.

-ms-overflow-style: none;

 

Shadows!

In all of the hamburger layout implementations that I’ve seen, there’s an inner shadow on the menus to make it appear as if the content is on a different plane than the menus. We can simply add this effect with a box-shadow on the left and right menu divs.

.menu-left {
    box-shadow: inset -5px 0 10px -2px rgba(0, 0, 0, 0.6);
}

.menu-right {
    box-shadow: inset 5px 0 10px -2px rgba(0, 0, 0, 0.6);
}

Add content

Now that we have the baseline layout created, now it’s just a matter of adding content. This this is a layout container, you can put anything inside!

Maybe some menu items in the left menu panel, some text in the content panel and a scrolling list in the right menu panel. As long as each panel doesn’t interfere with horizontal scrolling, you can go crazy and build highly interactive layouts. In this case, I add the pull to refresh behavior from a previous post.

Landscape, and bigger screens

What if we want to make this work in landscape, and on Windows 8 tablets, laptops and desktops? The great news is that since we used responsive layout techniques and controls, like grid, it already works great!

Get the code

So that’s it, we’ve fully implemented the hamburger button layout in a way that includes all of the important design elements, including touch interactivity.

The next step is to grab the code and integrate it into your app! Check out the Universal Project on GitHub:
https://github.com/dwcares/HamburgerLayout

5 thoughts on “Building a delicious “hamburger” button app layout

  1. Pingback: Dew Drop – May 6, 2014 (#1770) | Morning Dew

  2. leo

    Hi,
    How would I achieve the same thing with c#/XAML. I think alternative/better navigation and layout in general should be more prevalent in WP8 apps. When every app uses pivot or panorama just gets old sometimes..Thanks!

    Reply
    1. khoi

      I cannot agree more. Microsoft made a valiant effort to stand out with the metro design language and its influence is well documented. However it’s time for Microsoft to evolve with the times. Although I am a web dev and appreciate this template, most app devs would love to see this in xaml.

      Reply
  3. InAmberClad

    I really like this design, any chance of showing how to construct it for those of us who use XAML.

    Would be really appreciated, thanks.

    Reply
  4. DB Vehicle Electrics

    I do consider all of the ideas you’ve introduced for your post.
    They’re very convincing and will certainly work. Nonetheless, the posts are
    too brief for starters. May just you please extend them a bit from next time?
    Thank you for the post.

    Reply

Leave a Reply

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

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