www 101

All you need to know about the internet

Have a Question?

If you have any question you can ask below or enter what you are looking for!

How to Build an Off-Canvas Menu With CSS and a Touch of JavaScript

In this tutorial we’ll go through a simple yet effective method for creating an off-canvas menu with HTML, CSS, and JavaScript.

To get an initial idea of what we’ll be building, take a look at the related CodePen demo (check out the larger version for a better experience):

Note: This tutorial won’t focus on how to make the off-canvas menu accessible or responsive, so those would certainly be valid next steps.

1. Begin With Markup

Our markup consists of two wrapper elements:

  • the .top-banner element
  • the .top-nav element

Here’s the HTML code:

2. Next We Need Some CSS

With the markup ready, next let’s examine the most important styles which are required for our menu.

Note: For the sake of readability, this CSS code isn’t optimized—you’ll notice duplicate properties which you may want to strip out in your own version.

Styling the top-banner Element

The .top-banner element looks like this:

How the top-banner element looks like

Regarding its styles, we do the following:

  • Set its width equal to the window width minus the width of the .menu-wrapper element.
  • Set its height equal to the window height.
  • Define it as a flex container. This will force its overlay to cover the full parent height.
  • Use flexbox to vertically center the overlay’s content.

Here are the styles we’ll need to achieve all that: 

Styling the top-nav Element

The .top-nav element looks like this:

How the top-nav element looks like

In this case, we’ll do the following:

  • Specify the direct child elements as fixed positioned elements which cover the window height.
  • Use flexbox to vertically align the .fixed-menu element.
  • Hide the .menu-wrapper element by default. To do so, we don’t give it a property value such as display: none. In fact, we use the translate() function to move it 200px to the left. Keep in mind that the element’s width is 350px, so part of it is still within the viewport. However, it’s not visible because the element is positioned underneath the .fixed-menu element.
  • Hide the menu list.

Have a look at the corresponding CSS styles below:

3. Now for Some JavaScript

At this point, we’ll use some straightforward JavaScript code to manipulate the state of the off-canvas menu. 

Let’s describe the necessary actions:

  • When the .menu-open button is clicked, the menu should appear with a nice slide-in effect and the overlay should be pushed simultaneously to the right. Optionally, we can do a lot more things during this state. In our example, we add a box shadow to the ::before pseudo-element of the overlay and reveal the menu list using a fade-in effect.
  • When the .menu-close button is clicked, the menu should disappear with a nice slide-out effect, and the overlay should be pushed simultaneously to the left.

Here’s the JavaScript code which implements this behavior:

And below you’ll find the associated CSS styles:

4. Browser Support

This demo will work well only on desktop browsers. Mobile devices will require a different page layout, but that’s beyond the scope of this tutorial. As usual, we use Babel to compile the ES6 code down to ES5.

The only small issue I encountered while testing it is the text rendering change that happens when the overlay is being animated. Although I tried various approaches proposed in different Stack Overflow threads, I wasn’t able to find a straightforward solution for all operating systems and browsers. So keep in your mind that you might see small font rendering issues as the overlay is being animated.


That’s it, folks! We managed to build a useful off-canvas menu with relatively straightforward code. 

I hope you enjoyed the final result and you’ll use it as inspiration for creating even more powerful off-canvas menus. And of course, if you build any, don’t forget to share them with us!

Learn More Off-Canvas Techniques