A touch slideout navigation menu for your mobile web apps.

Overview

Slideout.js

NPM version License Build status Coverage Status Dependency status devDependency status downloads

A touch slideout navigation menu for your mobile web apps.

Features

  • Dependency-free.
  • Simple markup.
  • Native scrolling.
  • Easy customization.
  • CSS transforms & transitions.
  • Just 2 Kb! (min & gzip)

Demo

Check out the demo to see it in action (on your mobile or emulate touches on your browser).

Slideout.js demo

Installation

Slideout is available on cdnjs

<script src="https://cdnjs.cloudflare.com/ajax/libs/slideout/1.0.1/slideout.min.js"></script>

Also you can use one of many package managers

$ npm install slideout

$ spm install slideout

$ bower install slideout.js

$ component install mango/slideout

Usage

Implementing Slideout.js into your project is easy.

First of all, you'll need to create your markup. You should have a menu (#menu) and a main content (#panel) into your body.

<nav id="menu">
  <header>
    <h2>Menu</h2>
  </header>
</nav>

<main id="panel">
  <header>
    <h2>Panel</h2>
  </header>
</main>

Add the Slideout.js styles (index.css) in your web application.

body {
  width: 100%;
  height: 100%;
}

.slideout-menu {
  position: fixed;
  top: 0;
  bottom: 0;
  width: 256px;
  min-height: 100vh;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
  z-index: 0;
  display: none;
}

.slideout-menu-left {
  left: 0;
}

.slideout-menu-right {
  right: 0;
}

.slideout-panel {
  position: relative;
  z-index: 1;
  will-change: transform;
  background-color: #FFF; /* A background-color is required */
  min-height: 100vh;
}

.slideout-open,
.slideout-open body,
.slideout-open .slideout-panel {
  overflow: hidden;
}

.slideout-open .slideout-menu {
  display: block;
}

Then you just include Slideout.js, create a new instance with some options and call the toggle method:

<script src="dist/slideout.min.js"></script>
<script>
  var slideout = new Slideout({
    'panel': document.getElementById('panel'),
    'menu': document.getElementById('menu'),
    'padding': 256,
    'tolerance': 70
  });

  // Toggle button
  document.querySelector('.toggle-button').addEventListener('click', function() {
    slideout.toggle();
  });
</script>

Full example

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Slideout Demo</title>
    <meta http-equiv="cleartype" content="on">
    <meta name="MobileOptimized" content="320">
    <meta name="HandheldFriendly" content="True">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <style>
      body {
        width: 100%;
        height: 100%;
      }

      .slideout-menu {
        position: fixed;
        left: 0;
        top: 0;
        bottom: 0;
        right: 0;
        z-index: 0;
        width: 256px;
        overflow-y: scroll;
        -webkit-overflow-scrolling: touch;
        display: none;
      }

      .slideout-panel {
        position: relative;
        z-index: 1;
        will-change: transform;
      }

      .slideout-open,
      .slideout-open body,
      .slideout-open .slideout-panel {
        overflow: hidden;
      }

      .slideout-open .slideout-menu {
        display: block;
      }
    </style>
  </head>
  <body>

    <nav id="menu">
      <h2>Menu</h2>
    </nav>

    <main id="panel">
      <header>
        <button class="toggle-button"></button>
        <h2>Panel</h2>
      </header>
    </main>

    <script src="dist/slideout.min.js"></script>
    <script>
      var slideout = new Slideout({
        'panel': document.getElementById('panel'),
        'menu': document.getElementById('menu'),
        'padding': 256,
        'tolerance': 70
      });

      // Toggle button
      document.querySelector('.toggle-button').addEventListener('click', function() {
        slideout.toggle();
      });
    </script>

  </body>
</html>

Browser Support

  • Chrome (IOS, Android, desktop)
  • Firefox (Android, desktop)
  • Safari (IOS, Android, desktop)
  • Opera (desktop)
  • IE 10+ (desktop and mobile)

API

Slideout(options)

Create a new instance of Slideout.

  • options (Object) - Options to customize a new instance of Slideout.
  • options.panel (HTMLElement) - The DOM element that contains all your application content (.slideout-panel).
  • options.menu (HTMLElement) - The DOM element that contains your menu application (.slideout-menu).
  • [options.duration] (Number) - The time (milliseconds) to open/close the slideout. Default: 300.
  • [options.easing] (String) - The CSS effect to use when animating the opening and closing of the slideout. Default: ease. Possible values:
    • ease
    • linear
    • ease-in
    • ease-out
    • ease-in-out
    • step-start
    • step-end
    • cubic-bezier
  • [options.padding] (Number) - Default: 256.
  • [options.tolerance] (Number) - The number of px needed for the menu can be opened completely, otherwise it closes. Default: 70.
  • [options.touch] (Boolean) - Set this option to false to disable Slideout touch events. Default: true.
  • [options.side] (String) - The side to open the slideout (left or right). Default: left.
var slideout = new Slideout({
  'panel': document.getElementById('main'),
  'menu': document.getElementById('menu'),
  'padding': 256,
  'tolerance': 70,
  'easing': 'cubic-bezier(.32,2,.55,.27)'
});

Slideout.open();

Opens the slideout menu. It emits beforeopen and open events.

slideout.open();

Slideout.close();

Closes the slideout menu. It emits beforeclose and close events.

slideout.close();

Slideout.toggle();

Toggles (open/close) the slideout menu.

slideout.toggle();

Slideout.isOpen();

Returns true if the slideout is currently open, and false if it is closed.

slideout.isOpen(); // true or false

Slideout.destroy();

Cleans up the instance so another slideout can be created on the same area.

slideout.destroy();

Slideout.enableTouch();

Enables opening the slideout via touch events.

slideout.enableTouch();

Slideout.disableTouch();

Disables opening the slideout via touch events.

slideout.disableTouch();

Slideout.on(event, listener);

slideout.on('open', function() { ... });

Slideout.once(event, listener);

slideout.once('open', function() { ... });

Slideout.off(event, listener);

slideout.off('open', listener);

Slideout.emit(event, ...data);

slideout.emit('open');

Events

An instance of Slideout emits the following events:

  • beforeclose
  • close
  • beforeopen
  • open
  • translatestart
  • translate
  • translateend

The slideout emits translatestart, translate and translateend events only when it is opening/closing via touch events.

slideout.on('translatestart', function() {
  console.log('Start');
});

slideout.on('translate', function(translated) {
  console.log('Translate: ' + translated); // 120 in px
});

slideout.on('translateend', function() {
  console.log('End');
});

// 'Start'
// 'Translate 120'
// 'End'

data-slideout-ignore attribute

You can use the special HTML attribute data-slideout-ignore to disable dragging on some elements. For example, if you have to prevent slideout will open when touch on carousels, maps, iframes, etc.

<main id="panel">
  <header>
    <h2>Panel</h2>
  </header>
  <div id="carousel" data-slideout-ignore>
    <h2>Carousel</h2>
    ...
  </div>
</main>

npm-scripts

$ npm run build
$ npm run dist
$ npm test
$ npm run hint

FAQ

How to add a toggle button.

// vanilla js
document.querySelector('.toggle-button').addEventListener('click', function() {
  slideout.toggle();
});

// jQuery
$('.toggle-button').on('click', function() {
    slideout.toggle();
});

How to open slideout from right side.

You should use the side option with the value right.

var slideout = new Slideout({
  'panel': document.getElementById('content'),
  'menu': document.getElementById('menu'),
  'side': 'right'
});

How to enable slideout only on mobile devices.

You should use mediaqueries:

@media screen and (min-width: 780px) {
  .slideout-panel {
    margin-left: 256px;
  }

  .slideout-menu {
    display: block;
  }

  .btn-hamburger {
    display: none;
  }
}

Demo: http://codepen.io/pazguille/pen/mEdQvX

How to use slideout with a fixed header.

First, you should define the styles for your fixed header:

.fixed-header {
  position: fixed;
  width: 100%;
  height: 50px;
  backface-visibility: hidden;
  z-index: 2;
  background-color: red;
}

Then, using slideout's events you should translate the fixed header:

var fixed = document.querySelector('.fixed-header');

slideout.on('translate', function(translated) {
  fixed.style.transform = 'translateX(' + translated + 'px)';
});

slideout.on('beforeopen', function () {
  fixed.style.transition = 'transform 300ms ease';
  fixed.style.transform = 'translateX(256px)';
});

slideout.on('beforeclose', function () {
  fixed.style.transition = 'transform 300ms ease';
  fixed.style.transform = 'translateX(0px)';
});

slideout.on('open', function () {
  fixed.style.transition = '';
});

slideout.on('close', function () {
  fixed.style.transition = '';
});

Demo: http://codepen.io/pazguille/pen/ZBxdgw

How to disable dragging on some elements.

You can use the attribute data-slideout-ignore to disable dragging on some elements:

<nav id="menu">
  <header>
    <h2>Menu</h2>
  </header>
</nav>

<main id="panel">
  <header>
    <h2>Panel</h2>
  </header>
  <div id="carousel" data-slideout-ignore>
    <h2>Carousel</h2>
    ...
  </div>
</main>

How to add an overlay to close the menu on click.

You can do that using the powerful slideout API and a little extra CSS:

.panel:before {
  content: '';
  display: block;
  background-color: rgba(0,0,0,0);
  transition: background-color 0.5s ease-in-out;
}

.panel-open:before {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
  background-color: rgba(0,0,0,.5);
  z-index: 99;
}
function close(eve) {
  eve.preventDefault();
  slideout.close();
}

slideout
  .on('beforeopen', function() {
    this.panel.classList.add('panel-open');
  })
  .on('open', function() {
    this.panel.addEventListener('click', close);
  })
  .on('beforeclose', function() {
    this.panel.classList.remove('panel-open');
    this.panel.removeEventListener('click', close);
  });

Demo: http://codepen.io/pazguille/pen/BQYRYK

With ❤️ by

License

MIT license. Copyright © 2015 Mango.

Comments
  • Fixed Header Issues

    Fixed Header Issues

    http://codepen.io/xstortionist/pen/GordGp

    Noticed when testing that swipe doesn't work on fixed headers, you must swipe outside of the header in order for it to work properly.

    Also noticed when swiping there is latency within the animation of the fixed header until the class is added to the header.

    Thought I'd pass this along and hope it helps.

    opened by Creativenauts 15
  • Menu should use transform as well

    Menu should use transform as well

    Currently, the slide menu has z-index: 0 and the panel has z-index: 1. Why isn't the slide menu using translate instead? This would remove the need for z-indexes, which get messy really quick.

    Also with z-index, transparent backgrounds are a problem:

    buggy

    improvement Fixed 
    opened by aeneasr 10
  • Goes back to top if I reveal the menu

    Goes back to top if I reveal the menu

    When I browse the demo pages, after scrolling, if I open the menu, the pages scroll back to the top, losing my position.

    Tested on Chrome on Android 5.

    improvement 
    opened by pmtarantino 10
  • Added option to show menu from right-hand side

    Added option to show menu from right-hand side

    Now you can tell Slideout to open from the right-hand side of the screen:

    var slideout = new Slideout({
      'panel': doc.getElementById('panel'),
      'menu': doc.getElementById('menu-right'),
      'position': 'right'
    });
    

    Slideout Right side

    IMPORTANT NOTE: I had to add a method to set/unset visibility of the menu to hidden when it's closed, because having both a left and a right slideout, on small screens the right one would overlap the one on the left:

    Slideout Bug

    opened by Charca 9
  • Support for closing on click and edge slide in options.

    Support for closing on click and edge slide in options.

    It's common in mobile apps for the menu to only slide in when dragged from the edge of the screen (not the whole screen). The new grabWidth option will allow configuring what threshold this is. If not specified, the behaviour will revert back to how it currently is. I have also added an option to allow closing the menu when it's opened (closeOnClick) by simply clicking the panel element.

    opened by lewie9021 9
  • Unable to preventDefault inside passive event listener

    Unable to preventDefault inside passive event listener

    Hi, thank you for a great plugin. I found an issue, but I don't know how much it serious. You also can see this issue on your pluggin page. When I trying to open navigation by swiping from edge (not by tapping on the button) in mobile device emulation in Chrome devtools, I get the same error many times: Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080.

    question 
    opened by evanre 8
  • I want to create click => click on overlay close the menu">

    I want to create click => "overlay" => click on overlay close the menu

    Like in Waze, and most the of the Apps (Or like this - click on the dark area): http://materializecss.com/side-nav.html

    Better ui pattern!!

    Someone have codepen or guide? (Even for a pay i want to fix this. Send me massage her or in skype "siton-her").

    question 
    opened by Ezra-Siton-UIX 8
  • Scrolling not working on mobile devices

    Scrolling not working on mobile devices

    Got everything working great except that when the menu in the slide out is vertically longer that the viewport (very common in landscape orientation), the user can not scroll the menu vertically to reveal the rest of the menu items. This does work on desktop clients with the default ugly sidebars but seems to be entirely non functional on mobile touch devices.

    Even testing the demo at https://mango.github.io/slideout/ yields the same behavior. Am I missing something? It is otherwise a really great solution for us here. Please advise. Thank you!

    bug 
    opened by photon43 8
  • When you open the menu does not maintain the scroll position

    When you open the menu does not maintain the scroll position

    I have a problem in the mobile version of my website, that when opening the scroll menu is not respected and the site back to the top.

    Has anyone had this problem?

    opened by williamcosta 7
  • inner page links don't work on chrome (mobile & windows)

    inner page links don't work on chrome (mobile & windows)

    I'm having trouble getting inner page links in the navbar to work in Chrome (eg. <li><a href="/#foo">Foo</a></li> ) Works fine in Firefox. I'm using jQuery/bootstrap. No error; just nothing happens.

    opened by hardlynoticeable 7
  • Error Trying to Use Slideout Meteor package

    Error Trying to Use Slideout Meteor package

    Hello:

    I'm using the Meteor package version of Slideout and I get this error in my browser when the page loads:

    Uncaught TypeError: Cannot read property 'className' of null
    

    It appears to come at slideout.min.js:1. Any ideas? The package is chriswessels:slideout

    Thanks!

    invalid 
    opened by nicholasalanbrown 7
  • tolerance option need to discuss

    tolerance option need to discuss

    image

    must draw a ratio(h/w > ??) rectangle to open the slidemenu.

            rect.w = (e.pageX - this.offsetLeft) - rect.startX;
            rect.h = (e.pageY - this.offsetTop) - rect.startY;
            ratio = rect.h /rect.w > ?? && Math.abs(self._currentOffsetX) > self._tolerance
    
    
    
    opened by icai 0
  • CDN for new branch returns 404

    CDN for new branch returns 404

    The advertised URL for the new branch returns 404: <script src="https://cdnjs.cloudflare.com/ajax/libs/slideout/2.0.0/slideout.min.js"></script>

    opened by ilgrank 0
  • Right not working...

    Right not working...

    Hello guys, any with a "right" jsfiddle working demo? https://jsfiddle.net/zarza/xfqcev4b/2/

    We tried changing to 'side': 'right' but looks like it does not take effect.

    opened by zarza 0
Releases(v1.0.1)
  • v1.0.1(Nov 28, 2016)

  • v1.0.0(Nov 28, 2016)

    Features:

    • Add an attribute called data-slideout-ignore to disable dragging on some elements (maybe for a photo slider, carousel google map, iframes, etc).
    • Add classnames dynamically: .slideout-menu-left and .slideout-panel-left or .slideout-menu-right and .slideout-panel-right.
    • Use classList instead of regexp.
    • Use overflow-y: scroll; on .slideout-menu.

    Resolved issues:

    • https://github.com/Mango/slideout/issues/78
    • https://github.com/Mango/slideout/issues/196
    • https://github.com/Mango/slideout/issues/203
    • https://github.com/Mango/slideout/issues/200
    • https://github.com/Mango/slideout/issues/144

    Resolved PRs:

    • https://github.com/Mango/slideout/pull/157
    • https://github.com/Mango/slideout/pull/174
    • https://github.com/Mango/slideout/pull/95
    • https://github.com/Mango/slideout/pull/102
    • https://github.com/Mango/slideout/pull/161
    Source code(tar.gz)
    Source code(zip)
  • 0.1.12(Feb 2, 2016)

    Slideout

    • Add new events: translatestart and translateend.
    • Use translateX + will-change instead of translate3d.
    • Added code coverage.
    • Updated uglify-js dependency.

    Docs

    • Added tolerance option docs.
    • Added fixed header docs.
    • Added slideout only on mobile devices docs.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.11(Nov 3, 2015)

  • 0.1.10(Oct 30, 2015)

  • 0.1.9(May 4, 2015)

  • 0.1.8(May 4, 2015)

    • Added a side option to open the slideout from left or right.
    var slideout = new Slideout({
      'panel': document.getElementById('panel'),
      'menu': document.getElementById('menu'),
      'side': 'right'
    });
    
    • Update bower support.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.7(Apr 21, 2015)

    • Remove translate3d when slideout is closed (#51)
    • Now, an instance of slideout can emit the following events (#61):
      • beforeclose
      • close
      • beforeopen
      • open
      • translate

    The Slideout can emit translate event only when it is opening/closing via touch events.

    slideout.on('translate', function(translated) {
      console.log(translated); // eg. 120 in px
    });
    
    Source code(tar.gz)
    Source code(zip)
  • 0.1.6(Apr 8, 2015)

  • 0.1.5(Mar 10, 2015)

    • Fix back to top - (#5)
    • Use overflow:auto; instead of hidden - (#25)
    • Add spm support.
    • Corrected typos.
    • Use svg shields and add version shield.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.4(Mar 4, 2015)

  • 0.1.3(Mar 3, 2015)

  • 0.1.2(Mar 3, 2015)

A jQuery plugin that creates a paneled-style menu (like the type seen in the mobile versions of Facebook and Google, as well as in many native iPhone applications).

#jPanelMenu ###Version 1.4.1 jPanelMenu is a jQuery plugin for easily creating and managing off-canvas content. Check out the demo (and documentation)

Anthony Colangelo 927 Dec 14, 2022
stickUp a jQuery Plugin for sticky navigation menus.

stickUp a jQuery plugin A simple plugin that "sticks" an element to the top of the browser window while scrolling past it, always keeping it in view.

null 1.6k Dec 31, 2022
jQuery plugin to fire events when user's cursor aims at particular dropdown menu items. For making responsive mega dropdowns like Amazon's.

jQuery-menu-aim menu-aim is a jQuery plugin for dropdown menus that can differentiate between a user trying hover over a dropdown item vs trying to na

Ben Kamens 7.7k Dec 30, 2022
:zap: A sliding swipe menu that works with touchSwipe library.

Slide and swipe menu A sliding menu that works with touchSwipe library. Online demo Visit plugin site. Appszoom also uses it! So cool! What's the diff

Joan Claret 138 Sep 27, 2022
Quick access menu for the GNOME panel with options that help ease the workflow for newcomers and power users alike.

Tofu Menu (formerly Fedora Menu) Quick access menu for the GNOME panel with options that help ease the workflow for newcomers and power users alike. S

null 19 Sep 26, 2022
An experimental inline-to-menu-link animation based on a concept by Matthew Hall.

Inline to Menu Link Animation An experimental inline-to-menu-link animation based on a concept by Matthew Hall. Article on Codrops Demo Installation I

Codrops 35 Dec 12, 2022
Tippyjs - Tooltip, popover, dropdown, and menu library

Tippy.js The complete tooltip, popover, dropdown, and menu solution for the web Demo and Documentation ➡️ View the latest demo & docs here Migration G

James N 10.5k Dec 28, 2022
Slidebars is a jQuery Framework for Off-Canvas Menus and Sidebars into your website or web app.

Slidebars Slidebars is a jQuery Framework for Off-Canvas Menus and Sidebars into your website or web app. Version 2.0 is a complete rewrite which feat

Adam Smith 1.5k Jan 2, 2023
The best javascript plugin for app look-alike on- and off-canvas menus with sliding submenus for your website and webapp.

mmenu.js The best javascript plugin for app look-alike on- and off-canvas menus with sliding submenus for your website and webapp. It is very customiz

Fred Heusschen 2.6k Dec 27, 2022
The best javascript plugin for app look-alike on- and off-canvas menus with sliding submenus for your website and webapp.

mmenu.js The best javascript plugin for app look-alike on- and off-canvas menus with sliding submenus for your website and webapp. It is very customiz

Fred Heusschen 2.6k Dec 27, 2022
discord selected menu , discord selection menu , discord selec menu , discord select menu

Selected menu ihtiyacı olan arkadaşlar için paylaştım. Kodlar bana ait değildir githubdan bulduğum bir yerden alıp düzenledim. İşinize yarar örnek ekr

Wapper. 4 Jan 24, 2022
Navigation-Menu-Javascript - A simple Navbar navigation using vanilla javascript, to change links to the active link when clicked.

Navigation-Menu-Javascript A simple Navbar navigation using vanilla javascript, to change links to the active link when clicked. Desktop view Mobile v

Ellis 2 Feb 16, 2021
jSide Menu is a well designed, simple and clean side navigation menu with dropdowns.

jQuery jSide Menu jSide Menu is a well designed, simple and clean side navigation menu with dropdowns. Browse: Live Demo & Using Guide Main Features F

CodeHim 24 Feb 14, 2022
Super tiny size multi-touch gestures library for the web.    You can touch this →

Preview You can touch this → http://alloyteam.github.io/AlloyFinger/ Install You can install it via npm: npm install alloyfinger Usage var af = new Al

腾讯 AlloyTeam 3.3k Dec 12, 2022
Pressure is a JavaScript library for handling both Force Touch and 3D Touch on the web

Pressure is a JavaScript library for handling both Force Touch and 3D Touch on the web, bundled under one library with a simple API that makes working with them painless.

Stuart Yamartino 2.9k Dec 29, 2022
Smooth mobile touch slider for Mobile WebApp, HTML5 App, Hybrid App

iSlider iSlider is a lightweight, high-performant, no library dependencies cross-platform slide controller. It can help handling most sliding effects,

Baidu BEFE 1.7k Nov 25, 2022
Responsive navigation plugin without library dependencies and with fast touch screen support.

Responsive Nav Responsive navigation plugin without library dependencies and with fast touch screen support. Responsive Nav is a tiny JavaScript plugi

Viljami Salminen 4.1k Dec 29, 2022
An intro page with a full width background image, a bold animated menu and an iOS-like blurred effect behind the navigation

Full Page Intro & Navigation An intro page, focused around a full width background image and a bold animated menu. And, for browsers that support it,

CodyHouse 45 Sep 24, 2022
A javascript library for multi-touch gestures :// You can touch this

hammer.js A JavaScript library for detecting touch gestures. Installation NPM npm install --save hammerjs or Yarn yarn add hammerjs or CDN https://cdn

Hammer.js 23.3k Jan 1, 2023