Beautiful Multi-level Context Menu with Pure JavaScript and CSS3

Category: Javascript , Menu & Navigation | June 25, 2015
Author: ryanmorr
Views Total: 3,854
Official Page: Go to website
Last Update: June 25, 2015
License: MIT

Preview:

Beautiful Multi-level Context Menu with Pure JavaScript and CSS3

Description:

A beautiful multi-level context menu built with JavaScript and CSS that replaces the default browser right click menu and comes with a smooth pop-up animation based on CSS3 transitions and transforms.

How to use it:

Load the Font Awesome for menu icons.

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

Build the html structure for the multi-level context menu using nested lists.

<menu class="menu">
  <li class="menu-item">
    <button type="button" class="menu-btn"> <i class="fa fa-folder-open"></i> <span class="menu-text">Open</span> </button>
  </li>
  <li class="menu-item disabled">
    <button type="button" class="menu-btn"> <span class="menu-text">Open in New Window</span> </button>
  </li>
  <li class="menu-separator"></li>
  <li class="menu-item">
    <button type="button" class="menu-btn"> <i class="fa fa-reply"></i> <span class="menu-text">Reply</span> </button>
  </li>
  <li class="menu-item">
    <button type="button" class="menu-btn"> <i class="fa fa-star"></i> <span class="menu-text">Favorite</span> </button>
  </li>
  <li class="menu-item submenu">
    <button type="button" class="menu-btn"> <i class="fa fa-users"></i> <span class="menu-text">Social</span> </button>
    <menu class="menu">
      <li class="menu-item">
        <button type="button" class="menu-btn"> <i class="fa fa-comment"></i> <span class="menu-text">Comment</span> </button>
      </li>
      <li class="menu-item submenu">
        <button type="button" class="menu-btn"> <i class="fa fa-share"></i> <span class="menu-text">Share</span> </button>
        <menu class="menu">
          <li class="menu-item">
            <button type="button" class="menu-btn"> <i class="fa fa-twitter"></i> <span class="menu-text">Twitter</span> </button>
          </li>
          <li class="menu-item">
            <button type="button" class="menu-btn"> <i class="fa fa-facebook-official"></i> <span class="menu-text">Facebook</span> </button>
          </li>
          <li class="menu-item">
            <button type="button" class="menu-btn"> <i class="fa fa-google-plus"></i> <span class="menu-text">Google Plus</span> </button>
          </li>
          <li class="menu-item">
            <button type="button" class="menu-btn"> <i class="fa fa-envelope"></i> <span class="menu-text">Email</span> </button>
          </li>
        </menu>
      </li>
    </menu>
  </li>
  <li class="menu-separator"></li>
  <li class="menu-item">
    <button type="button" class="menu-btn"> <i class="fa fa-download"></i> <span class="menu-text">Save</span> </button>
  </li>
  <li class="menu-item">
    <button type="button" class="menu-btn"> <i class="fa fa-edit"></i> <span class="menu-text">Rename</span> </button>
  </li>
  <li class="menu-item">
    <button type="button" class="menu-btn"> <i class="fa fa-trash"></i> <span class="menu-text">Delete</span> </button>
  </li>
</menu>

The required CSS / CSS3 style rules.

.menu {
  position: absolute;
  width: 200px;
  padding: 2px;
  margin: 0;
  border: 1px solid #bbb;
  background: #eee;
  background: -webkit-linear-gradient(to bottom, #fff 0%, #e5e5e5 100px, #e5e5e5 100%);
  background: linear-gradient(to bottom, #fff 0%, #e5e5e5 100px, #e5e5e5 100%);
  z-index: 100;
  border-radius: 3px;
  box-shadow: 1px 1px 4px rgba(0,0,0,.2);
  opacity: 0;
  -webkit-transform: translate(0, 15px) scale(.95);
  transform: translate(0, 15px) scale(.95);
  transition: transform 0.1s ease-out, opacity 0.1s ease-out;
  pointer-events: none;
}

.menu-item {
  display: block;
  position: relative;
  margin: 0;
  padding: 0;
  white-space: nowrap;
}

.menu-btn {
  background: none;
  line-height: normal;
  overflow: visible;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  display: block;
  width: 100%;
  color: #444;
  font-family: 'Roboto', sans-serif;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  border: 1px solid transparent;
  white-space: nowrap;
  padding: 6px 8px;
  border-radius: 3px;
}
 .menu-btn::-moz-focus-inner, .menu-btn::-moz-focus-inner {
 border: 0;
 padding: 0;
}

.menu-text { margin-left: 25px; }

.menu-btn .fa {
  position: absolute;
  left: 8px;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.menu-item:hover > .menu-btn {
  color: #fff;
  outline: none;
  background-color: #2E3940;
  background: -webkit-linear-gradient(to bottom, #5D6D79, #2E3940);
  background: linear-gradient(to bottom, #5D6D79, #2E3940);
  border: 1px solid #2E3940;
}

.menu-item.disabled {
  opacity: .5;
  pointer-events: none;
}

.menu-item.disabled .menu-btn { cursor: default; }

.menu-separator {
  display: block;
  margin: 7px 5px;
  height: 1px;
  border-bottom: 1px solid #fff;
  background-color: #aaa;
}

.menu-item.submenu::after {
  content: "";
  position: absolute;
  right: 6px;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
  border: 5px solid transparent;
  border-left-color: #808080;
}

.menu-item.submenu:hover::after { border-left-color: #fff; }

.menu .menu {
  top: 4px;
  left: 99%;
}

.show-menu, .menu-item:hover > .menu {
  opacity: 1;
  -webkit-transform: translate(0, 0) scale(1);
  transform: translate(0, 0) scale(1);
  pointer-events: auto;
}

.menu-item:hover > .menu {
  -webkit-transition-delay: 100ms;
  transition-delay: 300ms;
}

The JavaScript to enable the context menu on the whole webpage.

var menu = document.querySelector('.menu');

function showMenu(x, y){
    menu.style.left = x + 'px';
    menu.style.top = y + 'px';
    menu.classList.add('show-menu');
}

function hideMenu(){
    menu.classList.remove('show-menu');
}

function onContextMenu(e){
    e.preventDefault();
    showMenu(e.pageX, e.pageY);
    document.addEventListener('click', onClick, false);
}

function onClick(e){
    hideMenu();
    document.removeEventListener('click', onClick);
}

document.addEventListener('contextmenu', onContextMenu, false);

One thought on “Beautiful Multi-level Context Menu with Pure JavaScript and CSS3

Leave a Reply