Codementor Events

Creating your own off-canvas responsive navigation with CSS & jQuery

Published Oct 08, 2017Last updated Feb 17, 2018
Creating your own off-canvas responsive navigation with CSS & jQuery

Off-canvas panels are one of the ideas making a website interesting nowadays. You can get them by default from a design framework like Zurb Foundation.

Quoted from Zurb Foundation:

Off-canvas panels are positioned outside of the viewport and slide in when activated. Setting up an off-canvas layout in Foundation is super easy.

There are plenty of third party plugins out there you can choose from as well.

The challenge

Though, not all of these plugins work as you wish, customising them could a pain. What about making your own off-canvas for a responsive navigation website such as the screenshot below?

download.png

A solution

It turns out to be quite easy using CSS & jQuery:

  1. Create a normal navigation with either Bootstrap or Foundation (I use Foundation):
<nav class="nav-main">

  <!-- row -->
  <div class="row row-nav">

    <!-- container -->
    <div class="grid-container">

      <!-- grid-x -->
      <div class="grid-x grid-padding-x">

        <div class="cell small-12 show-for-small-only">
          <a href="#" class="button-launch-off-canvas-menu vertical-center-left"><i class="material-icons">menu</i></a>
        </div>

        <div class="cell medium-12 hide-for-small-only">
          <ul class="dropdown menu align-center">
            <li><a href="#">One</a></li>
            <li><a href="#">Two</a>
              <ul class="menu nested vertical">
                <li><a href="#">Item 2A</a></li>
                <li><a href="#">Item 2B</a></li>
                <li><a href="#">Item 2C</a></li>
              </ul>
            </li>
            <li><a href="#">Three</a>
              <ul class="menu nested vertical">
                <li><a href="#">Item 3A</a></li>
                <li><a href="#">Item 3B</a></li>
                <li><a href="#">Item 3C</a></li>
              </ul>
            </li>
            <li><a href="#">Four</a></li>
          </ul>
        </div>

      </div>
      <!-- grid-x -->

    </div>
    <!-- container -->

  </div>
  <!-- row -->

</nav>
  1. Create the navigation that you want to display on the off-canvas on small screens:
<nav class="nav-off-canvas hide-for-medium hide-for-large">

  <!-- row -->
  <div class="row row-nav row-off-canvas">

    <!-- grid-x -->
    <div class="grid-x grid-padding-x off-canvas-background">
      <div class="cell small-8 cell-off-canvas">
        <a href="#" class="button-exit-off-canvas-menu"><i class="material-icons">close</i></a>
        <ul class="vertical menu accordion-menu align-left">
          <!-- to be appended via JavaScript -->
        </ul>
      </div>
    </div>
    <!-- grid-x -->

  </div>
  <!-- row -->

</nav>
  1. Create a .nav-off-canvas class in your CSS with position: fixed and set display: none:
.nav-off-canvas {
  display: none;
  position: fixed;
  z-index: 99999;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  width: 100%;
  height: 100%;
}
  1. Use jQuery to clone/ copy the inner elements of .menu.dropdown to .menu.accordion-menu:
// Define elements.
var menuDropdown = $('.menu.dropdown')
var menuAccordion = $('.menu.accordion-menu')

// Clone the inner elements of ul.menu.dropdown.
var $clone = menuDropdown.html()
menuAccordion.append($clone)
  1. Add jQuery .fadeIn method to nav.nav-off-canvas and .animate method to .cell.cell-off-canvas on the click event on .button-launch-off-canvas-menu button:
// Create off-canvas menu.
var navOffCanvas = $('.nav-off-canvas')
var buttonLaunch = $('.button-launch-off-canvas-menu')
var buttonExit = $('.button-exit-off-canvas-menu')

buttonLaunch.on('click', function () {
  navOffCanvas.fadeIn('fast')
  navOffCanvas.find('.cell-off-canvas').animate({
    width: 'toggle'
  }, 600, 'easeOutExpo')

  return false
})

buttonExit.on('click', function () {
  navOffCanvas.find('.cell-off-canvas').animate({
    width: 'toggle'
  }, 600, 'easeOutExpo')
  navOffCanvas.fadeOut('fast')

  return false
})

Suggestions

Let me know what you think and what would be your solutions. Anything suggestions, please leave a comment below. Hope this helps. You can get the source above on GitHub. You can see how it works here too.

Discover and read more posts from LAU TIAM KOK
get started
post commentsBe the first to share your opinion
Show more replies