Create a Simple Slideout Menu using Vanilla JS

One of the most important parts of any site is the navigation, especially with responsive design since you don’t always have much space to place with. That’s why I put together this super simple yet effective slide out menu, using good old fashioned HTML, CSS and Javascript. If you’re looking to get way from jQuery, this is definitely for you.

If you have a small site or you only need a few links showing in your main navigation, you should consider whether you actually need a hidden menu.

The HTML

First, layout the markup for your menu.

<nav id="slideout-menu" class="slideout-menu">
    <a id="slideout-close" class="slideout-close" href="#">&times;</a>
    <ul>
        <li><a href="#" title="Our homepage">Home</a></li>
        <li><a href="#" title="About CompanyX">About Us</a></li>
        <li><a href="#" title="Services we offer">Our Services</a></li>
        <li><a href="#" title="Get in touch!">Contact Us</a></li>
    </ul>
</nav>

<button id="slideout-toggle" class="slideout-toggle" href="#">
    <span></span>
    <span></span>
    <span></span>
</button>

Let’s break this down in to pieces.

<nav id="slideout-menu" class="slideout-menu">
    ...
</nav>

We’re using the HTML5 nav element, with an ID for toggling (more on this later) and a class for styling.

<button id="slideout-close" class="slideout-close" href="#">&times;</button>

Next, we create a button. This will be used for closing the menu when it’s open.

<ul>
    <li><a href="#" title="Our homepage">Home</a></li>
    <li><a href="#" title="About CompanyX">About Us</a></li>
    <li><a href="#" title="Services we offer">Our Services</a></li>
    <li><a href="#" title="Get in touch!">Contact Us</a></li>
</ul>

Now our navigation links.

<button id="slideout-toggle" class="slideout-toggle" href="#">
    <span></span>
    <span></span>
    <span></span>
</button>

Finally, we’ll create a simple but awesome looking hamburger button.

The CSS

Let’s make this thing look awesome!

body {
    color: #444;
    font-family: sans-serif;
    font-size: 14px;
}

.slideout-menu {
    background-color: #eee;
    padding: 42px 0;
    position: absolute;
    left: -280px;
    transition: left .4s;
    top: 0;
    height: 100vh;
    width: 280px;
}

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

.slideout-menu ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.slideout-menu ul li {
    display: block;
    margin: 0;
    padding: 0;
}

.slideout-menu ul li a {
    color: #555;
    display: block;
    font-size: 1.4em;
    padding: 8px 24px;
    text-decoration: none;
}

.slideout-menu a.slideout-close {
    color: #888;
    display: block;
    font-size: 2em;
    padding: 24px 42px;
    position: absolute;
    right: 0;
    top: 0;
    text-decoration: none;
}

.slideout-toggle {
    display: inline-block;
    padding: 24px;
    width: 18px;
}

.slideout-toggle span {
    background-color: #888;
    display: block;
    height: 2px;
    width: 100%;
    margin: 3px 0;
}

Alright, the breakdown. First, we want to style the menu itself.

.slideout-menu {
    background-color: #eee;
    padding: 42px 0;
    position: absolute;
    left: -280px;
    transition: left .4s;
    top: 0;
    height: 100vh;
    width: 280px;
}

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

To make sure it’s hidden from view, we’re positioning it absolutely and setting the value of left to -280px, which coincidently happens to be the width of the menu. If you change the width, be sure to amend the left value accordingly. There’s also a transition there so the menu appears nicely, not just like BAM! (Nobody needs that)

And of course, the is-open class. We’ll use this with our Javascript to show the menu when its toggled.

.slideout-menu ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.slideout-menu ul li {
    display: block;
    margin: 0;
    padding: 0;
}

.slideout-menu ul li a {
    color: #555;
    display: block;
    font-size: 1.4em;
    padding: 8px 24px;
    text-decoration: none;
}

The menu styling. I’ve opted for a simple, well spaced list (remember, we’re aiming this at mobile users so large tap targets are a must!)

.slideout-menu a.slideout-close {
    color: #888;
    display: block;
    font-size: 2em;
    padding: 24px 42px;
    position: absolute;
    right: 0;
    top: 0;
    text-decoration: none;
}

Next, the close button. Again, I’ve added plenty of padding so it’s easy to use from a mobile device. It looks pretty, too.

.slideout-toggle {
    display: inline-block;
    padding: 24px;
    width: 18px;
}

.slideout-toggle span {
    background-color: #888;
    display: block;
    height: 2px;
    width: 100%;
    margin: 3px 0;
}

And finally, the hamburger. Yum. This is quite simply some span tags styled to look like a burger.

The Javascript

Pulling it all together. Without this, our menu is pretty much useless. Now, before we go any further I just want to say this can of course be achieved, very easily, with jQuery but I wanted to create something that doesn’t require any frameworks.

Onwards…

document.addEventListener('DOMContentLoaded', function() {
    var menu, toggleButton, closeButton;

    // Set Elements
    menu = document.getElementById('slideout-menu');
    toggleButton = document.getElementById('slideout-toggle');
    closeButton = document.getElementById('slideout-close');

    // Toggle Menu
    toggleButton.addEventListener('click', function(e) {
        e.preventDefault();
        menu.classList.toggle('is-open');
    });

    // Close Menu
    closeButton.addEventListener('click', function(e) {
        e.preventDefault();
        menu.classList.remove('is-open');
    });
});

So, let’s break this down:

document.addEventListener('DOMContentLoaded', function() {
    ...
});

Before anything else, let’s make sure the DOM has loaded properly by listening out for the DOMContentLoaded event. For jQuery users, this is the same as $(document).ready.

var menu, toggleButton, closeButton;

// Set Elements
menu = document.getElementById('slideout-menu');
toggleButton = document.getElementById('slideout-toggle');
closeButton = document.getElementById('slideout-close');

Next, we’re defining a few variables that we’ll use and finding the elements we need to manipulate by their IDs (as I mentioned earlier).

// Toggle Menu
toggleButton.addEventListener('click', function(e) {
    e.preventDefault();
    menu.classList.toggle('is-open');
});

So now we’ve got our elements, we’re going to listen for clicks on the toggle button. (for jQuery, this would be $('#slideout-toggle').click(function(e)) {}) and then we add the is-open class if it’s not there, otherwise we remove it.

In my example, the toggle button is positioned in such a way that when the menu is open you can’t use it, but if it was visible, clicking it while the menu is open will close it.

// Close Menu
closeButton.addEventListener('click', function(e) {
    e.preventDefault();
    menu.classList.remove('is-open');
});

And finally, we listen out for clicks on our close button (inside the menu) and then remove the is-open class.

That’s it! You have an awesome slideout menu for your next site.

Demo

For a working demo, head over to Codepen :).