Mobile-first Morphing Navigation Menu With JavaScript And CSS3

Category: Javascript , Menu & Navigation , Recommended | February 15, 2018
Author: Stas Melnikov
Views Total: 358 views
Official Page: Go to website
Last Update: February 15, 2018
License: MIT

Preview:

Mobile-first Morphing Navigation Menu With JavaScript And CSS3

Description:

A mobile-first fullscreen hamburger navigation system that uses CSS3 transforms to achieve the morphing effects when opening and closing.

How to use it:

Create the navigation menu and hamburger menu toggle as follows:

<header class="header">
  <div class="hamburger">
    <button class="button hamburger__button js-menu__toggle">
      <span class="hamburger__label">Launch</span>
    </button>
  </div>
  <nav class="menu">
    <ul class="list menu__list">
      <li class="menu__group">
        <a href="#" class="link menu__link">Menu Item 1</a>
      </li>
      <li class="menu__group">
        <a href="#" class="link menu__link">Menu Item 2</a>
      </li>
      <li class="menu__group">
        <a href="#" class="link menu__link">Menu Item 3</a>
      </li>
      <li class="menu__group">
        <a href="#" class="link menu__link">Menu Item 4</a>
      </li>
      <li class="menu__group">
        <a href="#" class="link menu__link">Menu Item 5</a>
      </li>
      ...
    </ul>
  </nav>
</header>

The primary CSS styles for the menu.

.header{
  box-sizing: border-box;
  width: 100%;
  color: var(--colorWhite);

  display: flex;
  justify-content: center;

  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 9998;
}

.menu{
  box-sizing: border-box;
  width: 100%;
  padding-bottom: 55px;

  height: 0;
  transform: translate3d(0, -100%, 0);
  opacity: 0;

  display: flex;
  align-items: flex-end;

  position: fixed;
  top: 0;
  left: 0;
}

.menu__list{
  box-sizing: border-box;
  width: 100%;
  max-height: 100%;
  display: none;

  padding-top: 30px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.menu__group{
  padding: .5rem 3rem; 
  font-size: 3.2rem;
  font-weight: 700;
  text-transform: uppercase;
}

.menu__group_active{
  background-color: var(--colorWhite);
  color: var(--colorBlack);
}

.menu__item{
  padding: 8px 25px;
  display: block;
}

Style the hamburger menu toggle button.

.hamburger{
  position: relative;
  line-height: 1;
  padding-bottom: .5em;
}

.hamburger:before{
  content :"";
  width: 100px;
  height: 100px;
  background-color: var(--colorMain);
  border-radius: 50%;

  position: absolute;
  bottom: -55px;
  left: -35px;
}

.hamburger__button{
  width: 1.4em;
  height: 1em;
  font-size: 20px;

  position: relative;
  text-indent: -9999px;
  z-index: 2;
}

.hamburger__button:before, .hamburger__button:after, .hamburger__label{
  width: 100%;
  height: 20%;
  border-radius: 5px;
  background-color: currentColor;

  position: absolute;
  left: 0;
}

.hamburger__button:before, .hamburger__button:after{
  content:"";
}

.hamburger__button:before{
  top: 0;
}

.hamburger__button:after{
  bottom: 0;
}

.hamburger__button:focus{
  outline: none;
}

.hamburger__label{
  margin-top: -.1em;
  top: 50%;
}

The required CSS styles for the menu when activated.

.js-menu_activated{
  overflow: hidden;
}

.js-menu_activated .menu{
  height: 100%;
  transform: translate3d(0, 0, 0);
  opacity: 1;
}

.js-menu_activated .hamburger:before{
  width: 100vh;
  height: 100vh;
  transform: translate3d(-50vh, -50vh, 0) scale(5);
}

.js-menu_activated .menu__list{
  display: block;
}

.js-menu_activated .hamburger__button:before{
  transform: translate3d(0, -50%, 0) rotate(45deg);
  top: 50%;
}

.js-menu_activated .hamburger__button:after{
  transform: translate3d(0, -50%, 0) rotate(135deg);
  top: 50%;
}

.js-menu_activated .hamburger__label{
  transform: rotate(-45deg) translate3d(-5.71429px,-6px,0);
  opacity: 0;
}

The CSS for the morphing effects.

.menu{
  transition: opacity .2s ease-out;
}

.js-menu_activated .menu{
  will-change: opacity;
  transition-duration: .2s;
  transition-delay: .3s;
}

.hamburger:before{
  will-change: width, height;
  transition: transform .3s cubic-bezier(0.04, -0.1, 0.29, 0.98),
    width .3s cubic-bezier(0.04, -0.1, 0.29, 0.98),
    height .3s cubic-bezier(0.04, -0.1, 0.29, 0.98);
}

.js-menu_activated .hamburger:before{
  transition-duration: 1s;
}

.hamburger__button:before, .hamburger__button:after{
  transition-property: transform;
}

.hamburger__button:before, .hamburger__button:after, .hamburger__label{
  transition-timing-function: ease;
  transition-duration: .15s;
}

.hamburger__label{
  transition-property: transform, opacity;
}

The main JavaScript to toggle CSS classes when you toggle the menu.

(function(){
  'use strict';

  class Menu {
    constructor(settings) {
      this.nodeMenu = settings.nodeMenu;
      settings.nodeMenuButton.addEventListener('click', this.toggle.bind(this));
    }

    toggle() {
      return this.nodeMenu.classList.toggle('js-menu_activated');
    }
  }

  let nodeMenu = document.querySelector('body');
  
  new Menu({
    nodeMenu: nodeMenu,
    nodeMenuButton: nodeMenu.querySelector('.js-menu__toggle')
  });
})();

You Might Be Interested In:


Leave a Reply