Off Canvas Menu using JavaScript

Off Canvas Menu using JavaScript
Code Snippet:Off-screen Menu Concept
Author: Ondreas
Published: January 20, 2024
Last Updated: January 22, 2024
Downloads: 877
License: MIT
Edit Code online: View on CodePen
Read More

This JavaScript code provides an off-canvas menu functionality for your website. When a user clicks the navigation icon, the menu slides in from the right side. This feature is helpful for creating a clean and organized mobile-friendly navigation experience.

It offers a compact and user-friendly navigation solution. You can integrate this code on your website to implement an off-canvas menu, which is perfect for mobile and responsive designs.

How to Create Off Canvas Menu Using JavaScript

1. First of all, load the Normalize CSS and Google Fonts by adding the following CDN links into the head tag of your HTML document.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Raleway|Spectral'>

2. After that, create the HTML structure for the off-canvas menu. Include a navigation icon and the menu content. For instance, create a div with a unique class for the navigation icon and a nav element for the menu content.

<div class="navicon" id="navicon"><span></span></div>

<nav class="main-nav" id="main-nav" role="navigation">
	<ul class="main-nav__list">
		<li><a class="main-nav__link" href="#!0">&Uacute;vod</a></li>
		<li><a class="main-nav__link" href="#!0">Produkty</a></li>
		<li><a class="main-nav__link" href="#!0">Inform&aacute;cie</a></li>
		<li><a class="main-nav__link" href="#!0">Kontakt</a></li>
		<!--<li><a class="main-nav__link" href="#!0">Cart <span>(5)</span></a></li> -->
	</ul>
	<div class="main-nav__info">
		<p>Aktuálne novinky o nových motívoch svadobných oznamení, pozvánok a etikiet, nájdete aj na týchto sociálnych sieťach:</p>
	</div>
	<div class="main-nav__social">
		<a href="#!0" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64"><path d="M64,12.2c-2.4,1-4.9,1.8-7.5,2.1c2.7-1.6,4.8-4.2,5.8-7.3c-2.5,1.5-5.3,2.6-8.3,3.2C51.5,7.6,48.1,6,44.3,6 c-7.3,0-13.1,5.9-13.1,13.1c0,1,0.1,2,0.3,3C20.6,21.6,10.9,16.3,4.5,8.4c-1.1,1.9-1.8,4.2-1.8,6.6c0,4.6,2.3,8.6,5.8,10.9 c-2.2-0.1-4.2-0.7-5.9-1.6c0,0.1,0,0.1,0,0.2c0,6.4,4.5,11.7,10.5,12.9c-1.1,0.3-2.3,0.5-3.5,0.5c-0.8,0-1.7-0.1-2.5-0.2 c1.7,5.2,6.5,9,12.3,9.1c-4.5,3.5-10.2,5.6-16.3,5.6c-1.1,0-2.1-0.1-3.1-0.2C5.8,55.8,12.7,58,20.1,58c24.2,0,37.4-20,37.4-37.4 c0-0.6,0-1.1,0-1.7C60,17.1,62.2,14.8,64,12.2z"></path></svg></a>
		<a href="#!0" target="_blank"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64"><path d="M32,5.766c8.544,0,9.556,0.033,12.931,0.187c3.642,0.166,7.021,0.895,9.621,3.496 c2.6,2.6,3.329,5.979,3.496,9.621c0.154,3.374,0.187,4.386,0.187,12.931s-0.033,9.556-0.187,12.931 c-0.166,3.642-0.895,7.021-3.496,9.621c-2.6,2.6-5.98,3.329-9.621,3.496c-3.374,0.154-4.386,0.187-12.931,0.187 s-9.557-0.033-12.931-0.187c-3.642-0.166-7.021-0.895-9.621-3.496c-2.6-2.6-3.329-5.979-3.496-9.621 C5.798,41.556,5.766,40.544,5.766,32s0.033-9.556,0.187-12.931c0.166-3.642,0.895-7.021,3.496-9.621 c2.6-2.6,5.979-3.329,9.621-3.496C22.444,5.798,23.456,5.766,32,5.766 M32,0c-8.691,0-9.78,0.037-13.194,0.193 c-5.2,0.237-9.768,1.511-13.436,5.178C1.705,9.037,0.43,13.604,0.193,18.806C0.037,22.22,0,23.309,0,32 c0,8.691,0.037,9.78,0.193,13.194c0.237,5.2,1.511,9.768,5.178,13.436c3.666,3.666,8.234,4.941,13.436,5.178 C22.22,63.963,23.309,64,32,64s9.78-0.037,13.194-0.193c5.199-0.237,9.768-1.511,13.436-5.178c3.666-3.666,4.941-8.234,5.178-13.436 C63.963,41.78,64,40.691,64,32s-0.037-9.78-0.193-13.194c-0.237-5.2-1.511-9.768-5.178-13.436 c-3.666-3.666-8.234-4.941-13.436-5.178C41.78,0.037,40.691,0,32,0L32,0z"></path><path d="M32,15.568c-9.075,0-16.432,7.357-16.432,16.432c0,9.075,7.357,16.432,16.432,16.432 S48.432,41.075,48.432,32C48.432,22.925,41.075,15.568,32,15.568z M32,42.667c-5.891,0-10.667-4.776-10.667-10.667 c0-5.891,4.776-10.667,10.667-10.667c5.891,0,10.667,4.776,10.667,10.667C42.667,37.891,37.891,42.667,32,42.667z"></path><circle cx="49.082" cy="14.918" r="3.84"></circle></svg></a>
	</div>
	<ul class="main-nav__legal">
		<li><a class="main-nav__link" href="#!0">FAQ &amp; Shipping</a></li>
		<li><a class="main-nav__link" href="#!0">Obchodné podmienky</li>
	</ul>
</nav>

<div class="overlay"></div>

3. Now, utilize CSS to style the off-canvas menu. Apply styles to hide the menu off-screen initially and to manage its appearance and animations. Use classes like .main-nav, .navicon, and .overlay to structure and style your elements. These classes will handle animations, transitions, and positioning.

.squares {
  fill: none !important;
}

.is-hidden {
  display: none !important;
  visibility: hidden !important;
}

.visuallyhidden {
  position: absolute !important;
  clip: rect(0 0 0 0);
  -webkit-clip-path: inset(50%);
  clip-path: inset(50%);
  margin: -1px !important;
  padding: 0 !important;
  width: 1px !important;
  height: 1px !important;
  border: 0 !important;
  overflow: hidden;
  white-space: nowrap;
}
.visuallyhidden.is-focusable:active, .visuallyhidden.is-focusable:focus {
  position: static;
  clip: auto;
  -webkit-clip-path: none;
  clip-path: none;
  margin: 0;
  width: auto;
  height: auto;
  overflow: visible;
  white-space: inherit;
}

.is-invisible {
  visibility: hidden;
}

body{
  font-family: -apple-system, BlinkMacSystemFont, "avenir next", avenir, "Segoe UI", "lucida grande", "helvetica neue", helvetica, "Fira Sans", roboto, noto, "Droid Sans", cantarell, oxygen, ubuntu, "franklin gothic medium", "century gothic", "Liberation Sans", sans-serif;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-smoothing: antialiased;
  box-sizing: border-box;
position: relative;

}

*,
*:after,
*:before {
  box-sizing: inherit;
}

html,
body {
  margin: 0;
  padding: 0;
  width: 100%;
}

img {
  display: block;
  width: 100%;
  height: auto;
  border: 0;
}

figure {
  margin: 0;
}

.navicon {
  overflow: auto;
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 0.25rem;
  background-color: whitesmoke;
  z-index: 10;
  transition: all 680ms;
}
.navicon:hover {
  cursor: pointer;
  background-color: rgba(0, 0, 0, 0.05);
}
.navicon span {
  position: relative;
  margin-top: 6.75px;
  margin-bottom: 6.75px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -1.125px;
  transform: translateX(-50%);
}
.navicon span, .navicon span::before, .navicon span::after {
  display: block;
  width: 1.5rem;
  height: 2.25px;
  background-color: #767676;
  outline: 1px solid transparent;
  transition-property: background-color, transform;
  transition-duration: 0.34s;
}
.navicon span::before, .navicon span::after {
  position: absolute;
  content: "";
}
.navicon span::before {
  top: -6.75px;
}
.navicon span::after {
  top: 6.75px;
}

.js_is-active {
  background-color: crimson;
}
.js_is-active:hover {
  background-color: crimson;
}
.js_is-active span {
  background-color: transparent;
}
.js_is-active span::before {
  transform: translateY(6.75px) rotate(45deg);
}
.js_is-active span::after {
  transform: translateY(-6.75px) rotate(-45deg);
}
.js_is-active span::before, .js_is-active span::after {
  background-color: #fff;
}

.main-nav {
  z-index: 9;
  position: fixed;
  top: 0;
  right: 0;
  width: 100%;
  max-width: 515px;
  height: 100%;
  padding: 4rem 4rem 1rem 4rem;
  overflow-y: auto;
  background-color: #2a2a2a;
  transform: translateX(100%);
  transition: transform 0.55s cubic-bezier(0.785, 0.135, 0.15, 0.86);
}
.main-nav__list li {
  opacity: 0;
  transform: translateX(4rem);
  transition: all 0.3s ease;
}
.main-nav__link {
  display: block;
  padding: 1rem 0;
  color: #fff;
  font-family: "Raleway", sans-serif;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.25rem;
  text-decoration: none;
  text-transform: uppercase;
  transition: all 0.3s ease;
}
.main-nav__link:hover {
  color: #b7ac7f;
}
.main-nav__link span {
  color: #b7ac7f;
}
.main-nav__info {
  opacity: 0;
  margin: 1rem 0 2rem;
  color: #fff;
  font-family: "Spectral", serif;
  font-size: 1.05rem;
  letter-spacing: 0.0625rem;
  transform: translateY(30px);
  transition: all 0.4s ease;
}
.main-nav__social {
  opacity: 0;
  overflow: hidden;
  position: relative;
  margin-top: 2rem;
  padding-bottom: 2rem;
  transform: translateY(2rem);
  transition: all 0.4s ease;
}
.main-nav__social::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: -100%;
  width: 100%;
  height: 0.125rem;
  background-color: #b7ac7f;
}
.main-nav__social a {
  display: inline-block;
  width: 2rem;
  height: 2rem;
}
.main-nav__social a:not(:first-of-type) {
  margin-left: 2rem;
}
.main-nav__social a:hover path,
.main-nav__social a:hover circle {
  fill: #b7ac7f;
}
.main-nav__social svg {
  width: 100%;
  height: 100%;
}
.main-nav__social svg path,
.main-nav__social svg circle {
  fill: #fff;
  transition: all 0.3s ease;
}
.main-nav__legal {
  opacity: 0;
  margin-top: 2rem;
  transform: translateY(2rem);
  transition: all 0.4s ease;
}
.main-nav__legal li a {
  font-size: 0.9rem;
  transition: all 0.3s ease;
}
.main-nav__legal li a:hover {
  color: #b7ac7f;
}

.overlay {
  z-index: 1;
  opacity: 0;
  visibility: hidden;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(42, 42, 42, 0.75);
  transition: all 0.3s ease-in-out;
}

.js_show-menu {
  transform: translateX(0);
}
.js_show-menu .main-nav__list li {
  transform: translateX(0);
  opacity: 1;
}
.js_show-menu .main-nav__list li:nth-child(1) {
  transition-delay: 0.15s;
}
.js_show-menu .main-nav__list li:nth-child(2) {
  transition-delay: 0.3s;
}
.js_show-menu .main-nav__list li:nth-child(3) {
  transition-delay: 0.45s;
}
.js_show-menu .main-nav__list li:nth-child(4) {
  transition-delay: 0.6s;
}
.js_show-menu .main-nav__list li:nth-child(5) {
  transition-delay: 0.75s;
}
.js_show-menu .main-nav__list li:nth-child(6) {
  transition-delay: 0.9s;
}
.js_show-menu .main-nav__list li:nth-child(7) {
  transition-delay: 1.05s;
}
.js_show-menu .main-nav__list li:nth-child(8) {
  transition-delay: 1.2s;
}
.js_show-menu .main-nav__list li:nth-child(9) {
  transition-delay: 1.35s;
}
.js_show-menu .main-nav__list li:nth-child(10) {
  transition-delay: 1.5s;
}
.js_show-menu .main-nav__list li:nth-child(11) {
  transition-delay: 1.65s;
}
.js_show-menu .main-nav__list li:nth-child(12) {
  transition-delay: 1.8s;
}
.js_show-menu .main-nav__list li:nth-child(13) {
  transition-delay: 1.95s;
}
.js_show-menu .main-nav__list li:nth-child(14) {
  transition-delay: 2.1s;
}
.js_show-menu .main-nav__list li:nth-child(15) {
  transition-delay: 2.25s;
}
.js_show-menu .main-nav__list li:nth-child(16) {
  transition-delay: 2.4s;
}
.js_show-menu .main-nav__list li:nth-child(17) {
  transition-delay: 2.55s;
}
.js_show-menu .main-nav__list li:nth-child(18) {
  transition-delay: 2.7s;
}
.js_show-menu .main-nav__list li:nth-child(19) {
  transition-delay: 2.85s;
}
.js_show-menu .main-nav__list li:nth-child(20) {
  transition-delay: 3s;
}
.js_show-menu .main-nav__info,
.js_show-menu .main-nav__social,
.js_show-menu .main-nav__legal {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.85s;
}
.js_show-menu .main-nav__social::after {
  transform: translateX(100%);
  transition-property: transform;
  transition-duration: 340ms;
  transition-timing-function: ease-in;
  transition-delay: 0.95s;
}

.js_show-overlay {
  opacity: 0.8;
  visibility: visible;
}

ul {
  margin: 0;
  padding: 0;
  list-style-type: none;
}

p {
  margin: 0;
}

4. Finally, implement JavaScript functionalities for toggling the menu. The following code includes functions for adding, removing, and toggling classes. When the navigation icon is clicked, these functions are used to display or hide the menu by adding or removing specific classes.

// jQuery-style functions in pure JS
// hasClass, addClass, removeClass, toggleClass
// @author: Todd Motto
// @link: http://bit.ly/pure-js-jquery-style-functions
// @link: https://toddmotto.com/labs/reusable-js/

// hasClass
function hasClass(elem, className) {
  return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' ');
}

// addClass
function addClass(elem, className) {
  if (!hasClass(elem, className)) {
    elem.className += ' ' + className;
  }
}

// removeClass
function removeClass(elem, className) {
  var newClass = ' ' + elem.className.replace( /[\t\r\n]/g, ' ') + ' ';
  if (hasClass(elem, className)) {
    while (newClass.indexOf(' ' + className + ' ') >= 0 ) {
      newClass = newClass.replace(' ' + className + ' ', ' ');
    }
  elem.className = newClass.replace(/^\s+|\s+$/g, '');
  }
}

// toggleClass
function toggleClass(elem, className) {
  var newClass = ' ' + elem.className.replace( /[\t\r\n]/g, " " ) + ' ';
  if (hasClass(elem, className)) {
    while (newClass.indexOf(" " + className + " ") >= 0 ) {
      newClass = newClass.replace( " " + className + " " , " " );
    }
    elem.className = newClass.replace(/^\s+|\s+$/g, '');
  } else {
    elem.className += ' ' + className;
  }
}

//document.getElementById('navicon').onclick = function() {
    //toggleClass(this, 'js_is-active');
//}

var menu = document.querySelector('.main-nav'),
    navicon = document.querySelector('.navicon'),
	overlay = document.querySelector('.overlay');

navicon.onclick = function() {
	toggleClass(this, 'js_is-active');
    toggleClass(menu, 'js_show-menu');
	toggleClass(overlay, 'js_show-overlay');
};

overlay.onclick = function() {
	removeClass(navicon, 'js_is-active');
	removeClass(menu, 'js_show-menu');
	removeClass(this, 'js_show-overlay');
}

That’s all! hopefully, you have successfully created the Off-Canvas Menu Using JavaScript. If you have any questions or suggestions, feel free to comment below.

1 thought on “Off Canvas Menu using JavaScript”

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About CodeHim

Free Web Design Code & Scripts - CodeHim is one of the BEST developer websites that provide web designers and developers with a simple way to preview and download a variety of free code & scripts. All codes published on CodeHim are open source, distributed under OSD-compliant license which grants all the rights to use, study, change and share the software in modified and unmodified form. Before publishing, we test and review each code snippet to avoid errors, but we cannot warrant the full correctness of all content. All trademarks, trade names, logos, and icons are the property of their respective owners... find out more...

Please Rel0ad/PressF5 this page if you can't click the download/preview link

X