Simple Off-Canvas Navigation

It seems as if there are tons of examples or solutions available for off-canvas navigation. Each of these options seem to have their own use case but never seem to seamlessly integrate into what I have been looking for. What do you do when that is the situation? You create something that works and would be easy for others to use.


  • Responsive: This should be a given but it doesn’t always seem to be the case.
  • Easy to integrate
  • NO CODE-BLOAT!: Minimal use of JavaScript and clean Sass.
  • It should work!

This seems simple right? You’re correct. So let’s get start writing this.

Sass Structure

We’re going to start with our Sass structure. Some front-end developers allow this to become an afterthought or it will be the last part of their development process. I tend to lean toward making the Sass structure the most important part of the development process. My reasoning and thought process is:

  • What should happen when the page loads?
  • What should happen when a user clicks the icon to open the navigation?
  • What should happen once the navigation is open?
  • What should happen when a user clicks the icon to close the navigation?
  • How should the navigation adapt to different screen sizes? (This should not be an afterthought but a continual process running through our heads)

I’m a believer in writing Sass that is modular. What I mean by modular is that it can be used anywhere and lacks dependency. I also believe in using classes and allowing id’s to only be used as a form of identification in the HTML structure. Thus the tag name of “ID”.

Navigation Icon

This tutorial is not going to be a discussion of whether to use the infamous hamburger icon or not. Whether we are for or against, we can truthfully say that is has become the recognized visual element for navigation. We will first start with writing Sass that will create our icon for us.

Let’s take a look at the code to create the icon:

The code above utilizes before and after pseudo-elements to finish off the hamburger icon. With this approach, we eliminate the need for a font-icon or an image. This approach also allows us to animate the hamburger icon into a “X” to represent close (we will cover this later).

Off-Canvas Nav

Let’s take a look at what would be needed to create the off canvas navigation. It’s important that the navigation only be visible when the user triggers the nav.

Notice the CSS3 transform property that we have added to the.nav element. By usingtranslate and setting the x property to-100%, we are pushing the nav completely out of the visible window. This also allows the ability to later reset the x property and animate the nav on-screen.

Wrapping the Content

In most instances of off-canvas navigation, we see a shift of the content body when the nav opens up. To achieve this, we would need to wrap whatever is going to need to shift in an additional element. To do so, we can use the following Sass:

Notice that we are also using transform property for the page-wrap. We are sitting it cleanly to the left side of the browser window usingtranslate  with a x property of 0. We will change this state when the nav opens to give it an overall better feel and look.

What Happens When the Nav Opens

We need to account for the nav opening. To prepare for this, we’ll add a few additional styles to a few of the elements that we created earlier. Most notably, the nav, hamburger icon, and page-wrap.

Notice that the nav and page–wrap elements now have different values for the x property in the transform. We are telling the nav to now sit at the x-axis position of 0 in the window while the page–wrap will move over 75% to the left of its current x-axis position of 0. We also addedoverflow: hidden to the page–wrap element to keep a horizontal scroll bar from appearing.

Lastly, we are rotating the before and after pseudo elements to now become an “X” instead of the hamburger icon. The X clearly denotes that you click this icon in order to close the nav. To do so, we are once again utilizingtransform  but instead oftranslate , we userotate . Rotating the:before pseudo-element by 45 degrees and the:after  pseudo-element will create an “X”. Also note that for the.nav__toggle--span  element, we set the background to be transparent. This is to prevent the “X” from having a line through it.

JavaScript Goodness

All of this Sass is good but we still have to make the navigation open and close. This is where I feel most off-canvas solutions fall short. These actions can be achieved with a minimal amount of JavaScript but we choose to load up hundreds of lines of code or use a bloated plugin that requires an additional framework.

The following lines of JavaScript will cleanly apply the states needed for the off-canvas navigation to smoothly open and close:

We are initially creating variables for the elements that we will use in the off-canvas navigation. After this, we write a simple function to toggle a new class to the nav and page wrap. In this function, we are toggling a new class of.nav--open to the nav and page wrap. And finally, we add an event listener to the nav toggle button that will run thetoggleNav function on a click.


As you can see, from a code perspective, this is a pretty clean and easy way to create an off-canvas navigation. But wait, I want to see this in action! No worries, check out a CodePen of the nav.