Creating a Swipeable Side Menu for the Web

Creating a Swipeable Side Menu for the Web

Today, I will be sharing an experiment to replicate the behavior of the side menu, similar to what you’ve seen on smartphone applications, but this tutorial is for the web. I will take you through each step from structuring your layout and adding swipe gestures to open/close the menu, usable on both desktop and smartphones.

Note: This tutorial will require jQuery Library, so make sure you include the latest jQuery library to your HTML page before continuing.

Creating a Swipeable Side Menu for the Web

[tut demo=”http://www.onextrapixel.com/examples/touch-swipe/demo3.php” download=”http://www.onextrapixel.com/examples/touch-swipe/touch-swipe.zip”]

Creating a Swipeable Side Menu for the Web

1. Structure

HTML:

<div class="container">
    <div id="sidebar">
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">Explore</a></li>
            <li><a href="#">Users</a></li>
            <li><a href="#">Sign Out</a></li>
        </ul>
    </div>
    <div class="main-content">
    </div>
</div>

CSS:

body, html {
    height: 100%;
    margin: 0;
    overflow:hidden;
    font-family: helvetica;
    font-weight: 100;
}
.container {
    position: relative;
    height: 100%;
    width: 100%;
}

#sidebar {
    position: absolute;
    background: #DF314D;
    width: 240px;
    height: 100%;
    box-sizing: border-box;
   -moz-box-sizing: border-box;
}
#sidebar ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
#sidebar ul li {
    margin: 0;
}
#sidebar ul li a {
    padding: 15px 20px;
    font-size: 16px;
    font-weight: 100;
    color: white;
    text-decoration: none;
    display: block;
    border-bottom: 1px solid #C9223D;
    -webkit-transition:  background 0.3s ease-in-out;
    -moz-transition:  background 0.3s ease-in-out;
    -ms-transition:  background 0.3s ease-in-out;
    -o-transition:  background 0.3s ease-in-out;
    transition:  background 0.3s ease-in-out;
}
#sidebar ul li:hover a {
    background: #C9223D;
}

In the first step, we are laying out the structure for the left side menu that we will eventually hide to the left. I’ve added some basic styles for the demo, so feel free to change the look and feel of your side menu. I’ve also added an empty div called main-content. This div will be the container for the elements you want to show on this page. We’ll fill this up in the next step.

[tut demo=”http://www.onextrapixel.com/examples/touch-swipe/demo1.php”]

2. Building a Basic Side Menu

HTML:

<div class="container">
    <div id="sidebar">
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">Explore</a></li>
            <li><a href="#">Users</a></li>
                <li><a href="#">Sign Out</a></li>
        </ul>
    </div>
    <div class="main-content">
        <a href="#" data-toggle=".container" id="sidebar-toggle">
            <span class="bar"></span>
            <span class="bar"></span>
            <span class="bar"></span>
        </a>
        <div class="content">
            <h1>Creating Swipeable Side Menu For the Web</h1>
            <p>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
        </div>
    </div>
    </div>
</div>

CSS:

body, html {
    height: 100%;
    margin: 0;
    overflow:hidden;
    font-family: helvetica;
    font-weight: 100;
}
.container {
    position: relative;
    height: 100%;
    width: 100%;
    left: 0;
    -webkit-transition:  left 0.4s ease-in-out;
    -moz-transition:  left 0.4s ease-in-out;
    -ms-transition:  left 0.4s ease-in-out;
    -o-transition:  left 0.4s ease-in-out;
    transition:  left 0.4s ease-in-out;
}

.container.open-sidebar {
    left: 240px;
}

#sidebar {
    position: absolute;
    left: -240px;
    background: #DF314D;
    width: 240px;
    height: 100%;
    box-sizing: border-box;
}
#sidebar ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
#sidebar ul li {
    margin: 0;
}
#sidebar ul li a {
    padding: 15px 20px;
    font-size: 16px;
    font-weight: 100;
    color: white;
    text-decoration: none;
    display: block;
    border-bottom: 1px solid #C9223D;
    -webkit-transition:  background 0.3s ease-in-out;
    -moz-transition:  background 0.3s ease-in-out;
    -ms-transition:  background 0.3s ease-in-out;
    -o-transition:  background 0.3s ease-in-out;
    transition:  background 0.3s ease-in-out;
}
#sidebar ul li:hover a {
    background: #C9223D;
}
.main-content {
    width: 100%;
    height: 100%;
    padding: 10px;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    position: relative;
}
.main-content .content{
    box-sizing: border-box;
    -moz-box-sizing: border-box;
padding-left: 60px;
width: 100%;
}
.main-content .content h1{
    font-weight: 100;
}
.main-content .content p{
    width: 100%;
    line-height: 160%;
}
.main-content #sidebar-toggle {
    background: #DF314D;
    border-radius: 3px;
    display: block;
    position: relative;
    padding: 10px 7px;
    float: left;
}
.main-content #sidebar-toggle .bar{
     display: block;
    width: 18px;
    margin-bottom: 3px;
    height: 2px;
    background-color: #fff;
    border-radius: 1px;   
}
.main-content #sidebar-toggle .bar:last-child{
     margin-bottom: 0;   
}

JS:

$(document).ready(function() {
  $("[data-toggle]").click(function() {
    var toggle_el = $(this).data("toggle");
    $(toggle_el).toggleClass("open-sidebar");
  });
});

Now, we hide the side menu to the left with position:relative and left: -240px (the number is equivalent to the width of the sidebar). I’ve added a button and a jQuery script that will allow us to activate the side menu with a click by toggling a class open-sidebar to the container of both the sidebar and the main-content.

I then simply move the whole container to the left by 240px making the left side menu appear. If the user clicks on the button again, the jQuery script will remove the class and the side menu will disappear. In order to make the side menu animate as if it flew in from the left, I have also added a transition style to create an equivalent experience to what you get on your smartphone’s apps.

Now we have the basic side menu that can activated with a mouse click.

[tut demo=”http://www.onextrapixel.com/examples/touch-swipe/demo2.php”]

3. Making it Swipeable

HTML:

<div class="container">
    <div id="sidebar">
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">Explore</a></li>
            <li><a href="#">Users</a></li>
                <li><a href="#">Sign Out</a></li>
        </ul>
    </div>
    <div class="main-content">
        <div class="swipe-area"></div>
        <a href="#" data-toggle=".container" id="sidebar-toggle">
            <span class="bar"></span>
            <span class="bar"></span>
            <span class="bar"></span>
        </a>
        <div class="content">
            <h1>Creating Swipeable Side Menu For the Web</h1>
            <p>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
        </div>
    </div>
</div>

CSS:

body, html {
    height: 100%;
    margin: 0;
    overflow:hidden;
    font-family: helvetica;
    font-weight: 100;
}
.container {
    position: relative;
    height: 100%;
    width: 100%;
    left: 0;
    -webkit-transition:  left 0.4s ease-in-out;
    -moz-transition:  left 0.4s ease-in-out;
    -ms-transition:  left 0.4s ease-in-out;
    -o-transition:  left 0.4s ease-in-out;
    transition:  left 0.4s ease-in-out;
}
.container.open-sidebar {
    left: 240px;
}

.swipe-area {
    position: absolute;
    width: 50px;
    left: 0;
top: 0;
    height: 100%;
    background: #f3f3f3;
    z-index: 0;
}
#sidebar {
    background: #DF314D;
    position: absolute;
    width: 240px;
    height: 100%;
    left: -240px;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
}
#sidebar ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
#sidebar ul li {
    margin: 0;
}
#sidebar ul li a {
    padding: 15px 20px;
    font-size: 16px;
    font-weight: 100;
    color: white;
    text-decoration: none;
    display: block;
    border-bottom: 1px solid #C9223D;
    -webkit-transition:  background 0.3s ease-in-out;
    -moz-transition:  background 0.3s ease-in-out;
    -ms-transition:  background 0.3s ease-in-out;
    -o-transition:  background 0.3s ease-in-out;
    transition:  background 0.3s ease-in-out;
}
#sidebar ul li:hover a {
    background: #C9223D;
}
.main-content {
    width: 100%;
    height: 100%;
    padding: 10px;
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    position: relative;
}
.main-content .content{
    box-sizing: border-box;
    -moz-box-sizing: border-box;
padding-left: 60px;
width: 100%;
}
.main-content .content h1{
    font-weight: 100;
}
.main-content .content p{
    width: 100%;
    line-height: 160%;
}
.main-content #sidebar-toggle {
    background: #DF314D;
    border-radius: 3px;
    display: block;
    position: relative;
    padding: 10px 7px;
    float: left;
}
.main-content #sidebar-toggle .bar{
     display: block;
    width: 18px;
    margin-bottom: 3px;
    height: 2px;
    background-color: #fff;
    border-radius: 1px;   
}
.main-content #sidebar-toggle .bar:last-child{
     margin-bottom: 0;   
}

JS:

$(document).ready(function() {
  $("[data-toggle]").click(function() {
    var toggle_el = $(this).data("toggle");
    $(toggle_el).toggleClass("open-sidebar");
  });
    
});

$(".swipe-area").swipe({
    swipeStatus:function(event, phase, direction, distance, duration, fingers)
        {
            if (phase=="move" && direction =="right") {
                 $(".container").addClass("open-sidebar");
                 return false;
            }
            if (phase=="move" && direction =="left") {
                 $(".container").removeClass("open-sidebar");
                 return false;
            }
        }
});

The most tricky part of this tutorial is to make the side menu swipeable on both smartphone browsers and web browsers. At this stage, we will need to include a great third party plugin called TouchSwipe built by Matt Bryson which will handle the swipe gesture action for us. Make sure you include this plugin in your html file before you continue.

Now, that we have a way to detect swipe/drag action, we will use this to activate the side menu. The problem I had previously was that I applied the swipe action to the whole page and this proved to be a problem on smartphones because when you zoomed in, you would want to swipe left/right to navigate. By applying the swipe action to the whole page, every time the user wants to navigate left/right, it will activate the side menu by accident.

As this was unacceptable, I have added an empty div with a class name swipe-area to determine the swipeable area (I’ve highlighted this area for the purpose of this tutorial). This swipeable area is positioned at the left edge of the page so that the user will be able to activate the side menu by swiping right from the left edge of their screen. This solves the problem of activating it by accident when navigating.

In our JS above, we are detecting a swipe action using swipe() function provided by the TouchSwipe plugin. We are detecting 2 parts of the swipe action, the movement and the direction. We simply add an “open-sidebar” class to activate the side menu when the cursor/finger is moving to the right. We remove the class if the cursor/finger moves in the opposite direction.

In my experiment, this works perfectly on smartphones but doesn’t work well on desktop browsers because when we are dragging our cursors, the browsers will activate the text selection tool which overwrites our swipe action. We don’t want this, so that’s why we have return false after we add/remove the “open-sidebar” when swiping/dragging. By returning false right away, it prevents the text selection tool being activated by default.

[tut demo=”http://www.onextrapixel.com/examples/touch-swipe/demo3.php” download=”http://www.onextrapixel.com/examples/touch-swipe/touch-swipe.zip”]

Conclusion

And that’s it! We now have a swipeable side menu that works on both the desktop and smartphones browsers. Hope you like this tutorial, and if you have any questions or suggestions, feel free to leave a comment below.

Pete is a Bangkok entrepreneur, a UI designer, and a Ruby on Rails developer. He is the founder of Bucketlistly.com and MyColorscreen.com. Other than his businesses, design and development, he also loves astronomy, indie music, and blogging.

Comments

    • Neo Asterix,
    • June 27, 2013
    / Reply

    With a couple of rows of code you can make this work with Windows 8 touch devices, at the moment it doesn’t work.

    • massimo colella,
    • June 28, 2013
    / Reply

    great article.
    actually i’m developing a similar situation: a mobile oriented website, with left and right side menu. because i don’t want the client to download all that jquery stuff, i voted for move.js (for animation and property changes) and quo.js for the event and some basic js stuff. all in less than 30kb, included my script.
    right side menu is a lttle bit trickier than the left one, because of interaction with the width of the page, but i think i got a good solution. I hope to post my experiment soon.

    • Vel Murugan S,
    • July 4, 2013
    / Reply

    Wonderful way of flow…

    • alex.karatai,
    • September 11, 2013
    / Reply

    how to make this menu on the right?? pls help

      • Christopher Burkhouse,
      • November 8, 2013
      / Reply

      To do so would require basic knowledge of HTML/CSS. You simple edit the portions of code pertaining to alignment. Common sense would dictate first trying to replace all ‘left’ alignments to ‘right,’ or at least that’s what I’d do.

    • MikeSteve,
    • December 1, 2013
    / Reply

    Hello Peter… This is fantastic. However, to make the menu disappears, instead of clicking on the red button again… how do we make it behaves like standard menu way where you click anywhere else will cancel its appearance?

    • Martin Wiegand,
    • October 6, 2015
    / Reply

    Its broken. Its not scrollable. It only seems to work because of the few content.

Leave a Reply

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

Deals

Iconfinder Coupon Code and Review

Iconfinder offers over 1.5 million beautiful icons for creative professionals to use in websites, apps, and printed publications. Whatever your project, you’re sure to find an icon or icon…

WP Engine Coupon

Considered by many to be the best managed hosting for WordPress out there, WP Engine offers superior technology and customer support in order to keep your WordPress sites secure…

InMotion Hosting Coupon Code

InMotion Hosting has been a top rated CNET hosting company for over 14 years so you know you’ll be getting good service and won’t be risking your hosting company…

SiteGround Coupon: 60% OFF

SiteGround offers a number of hosting solutions and services for including shared hosting, cloud hosting, dedicated servers, reseller hosting, enterprise hosting, and WordPress and Joomla specific hosting.