Free Vanilla JS Accordion Menu Nested With Vanilla JS

🚀 Vanilla JS Accordion List – No automation building tools. Copy / Paste and Ready to Use. A multi-level animated accordion menu built with a nested navigation menu and JavaScript vanilla. CSS and JS are embedded within the HTML file. 

nested accordion, nested accordion jquery, nested accordion html, nested accordion javascript, nested accordion bootstrap

Requirements
Browser. No Node.js, Spinning, NPM, Webpack, Gulp, etc …

Quick start: install
Copy/paste and use.

How to make use of it:

1. The required markup structure for the nested accordion menu.

<div class="accordion-menu-wrapper active" id="menu-parent" data-accordion-wrapper>
  <nav role="navigation" class="accordion-menu">
    <ul class="accordion-menu__list">
      <li class="accordion-menu__item">
        <a
          href="#menu-1"
          class="accordion-menu__link"
          data-accordion-menu>
          <span>
            Menu 1 Dropdown
          </span>
          <span class="accordion-menu__icon"></span>
        </a>
        <ul class="accordion-menu__sublist accordion-menu--hidden" id="menu-1">
          <li>
            <a href="#" class="accordion-menu__sublink">
              Child Menu 1
            </a>
          </li>
          <li>
            <a
              href="#menu-1-1"
              class="accordion-menu__link"
              data-accordion-menu>
              <span>
                Child Menu 2 Dropdown
              </span>
              <span class="accordion-menu__icon"></span>
            </a>
            <ul class="accordion-menu__sublist accordion-menu--hidden" id="menu-1-1">
              <li>
                <a href="#" class="accordion-menu__sublink">
                  Grand Child Menu 1
                </a>
              </li>
              <li>
                <a href="#" class="accordion-menu__sublink">
                  Grand Child Menu 2
                </a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li class="accordion-menu__item">
        <a
          href="#menu-2"
          class="accordion-menu__link"
          data-accordion-menu>
          <span>
            Menu 2 Dropdown
          </span>
          <span class="accordion-menu__icon"></span>
        </a>
        <ul class="accordion-menu__sublist accordion-menu--hidden" id="menu-2">
          <li>
            <a href="#" class="accordion-menu__sublink">
              Child Menu 2
            </a>
          </li>
          <li>
            <a
              href="#menu-2-1"
              class="accordion-menu__link"
              data-accordion-menu>
              <span>
                Child Menu 2 Dropdown
              </span>
              <span class="accordion-menu__icon"></span>
            </a>
            <ul class="accordion-menu__sublist accordion-menu--hidden" id="menu-2-1">
              <li>
                <a href="#" class="accordion-menu__sublink">
                  Grand Child Menu 1
                </a>
              </li>
              <li>
                <a href="#" class="accordion-menu__sublink">
                  Grand Child Menu 2
                </a>
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li class="accordion-menu__item">
        <a href="#" class="accordion-menu__link">
          Submenu item
        </a>
      </li>        
    </ul>
  </nav>
</div>

2. The primary styling of the nested accordion menu.

.accordion-menu--hidden {
  display: none;
}    

.accordion-menu__list,
.accordion-menu__sublist {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.accordion-menu__list {
  border-top: 1px #eee solid;
}

.accordion-menu__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px #eee solid;
}

.accordion-menu__icon {
  position: relative;
  width: 16px;
  height: 16px;
  transition: .2s all;     
}

.accordion-menu__icon:before,
.accordion-menu__icon:after {
  content: "";
  display: block;
  background-color: #333;
  position: absolute;   
  top: 50%; left: 0;
  transition: .35s;
  width: 100%;
  height: 2px; 
}

.accordion-menu__icon:before {
  transform: translateY(-50%);
}

.accordion-menu__icon:after {
  transform: translateY(-50%) rotate(90deg);
}

.accordion-menu--active .accordion-menu__icon:before {
  transform: translateY(-50%) rotate(-90deg);
  opacity: 0;
}

.accordion-menu--active .accordion-menu__icon:after {
  transform: translateY(-50%) rotate(0);
}

.accordion-menu__sublist {
  margin-left: 1.25rem;
}

.accordion-menu__sublink {
  display: block;
  padding-top: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px #eee solid;
}

.accordion-menu-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 1rem;
  overflow: scroll;
}

.accordion-menu-nav__link:not(:last-child) {
  margin-right: 1rem;
}

.accordion-menu-wrapper {
  display: none;
}

.accordion-menu-wrapper.active {
  display: block;
}

3. The most important function.

var accordionMenu = function () {
    /**
    * Element.closest() polyfill
    * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
    */
    if (!Element.prototype.closest) {
      if (!Element.prototype.matches) {
        Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
      }
      Element.prototype.closest = function (s) {
        var el = this;
        var ancestor = this;
        if (!document.documentElement.contains(el)) return null;
        do {
          if (ancestor.matches(s)) return ancestor;
          ancestor = ancestor.parentElement;
        } while (ancestor !== null);
        return null;
      };
    }
    // Listen for click on the document
    // Accordiom menu functionality
    document.addEventListener('click', function (event) {
      // Bail if our clicked element doesn't match
      var trigger = event.target.closest('[data-accordion-menu]');
      if (!trigger) return;
      // Get the target content
      var target = document.querySelector(trigger.hash);
      if (!target) return;
      // Prevent default link behavior
      event.preventDefault();
      // Toggle our content
      target.classList.toggle('accordion-menu--hidden');
      // Toggle trigger class
      trigger.classList.toggle('accordion-menu--active');
    });
    // Listen for click on the document
    // Accordion parent menu functionality
    document.addEventListener('click', function (event) {
      // Bail if our clicked element doesn't match
      var trigger = event.target.closest('[data-accordion-menu-nav]');
      if (!trigger) return;
      // Get the target content
      var target = document.querySelector(trigger.hash);
      if (!target) return;
      // Prevent default link behavior
      event.preventDefault();
      // If the content is already expanded, collapse it and quit
      if (target.classList.contains('active')) {
        target.classList.remove('active');
        return;
      }
      // Get all open accordion content, loop through it, and close it
      var accordions = document.querySelectorAll('[data-accordion-wrapper]');
      for (var i = 0; i < accordions.length; i++) {
        accordions[i].classList.remove('active');
      }
      // Toggle our content
      target.classList.toggle('active');
    });
};

4. Activate the nested accordion menu.

accordionMenu();

Nested Accordion Menu, JS Accordion Menu Nested Plugin/Github, nested accordion material ui


See Demo And Download

Official Website(tomaszbujnowicz): Click Here

This superior jQuery/javascript plugin is developed by tomaszbujnowicz. For extra Advanced Usages, please go to the official website.

Related Posts

Fullscreen-Lightbox-Plugin

Simple And Powerful Fullscreen Lightbox Plugin | fslightbox

Fullscreen Lightbox Basic is a modern and handy plug-in for displaying photos and videos in a clean overlay box. Showcase a single source or create a great…

product-thumbnail-slider-with-zoom-effect-jquery

Product Thumbnail Slider With Positive Zoom Effect jQuery

Positive Zoom is a JavaScript library for creating an image gallery where you can zoom in on the current image by hovering over it. Must Read: Pure…

CSS-Gauge-Meter

Create Responsive Gauge Meter Using Pure CSS | CSSGauge

Pure CSS Gauge Meter Component, no SVG, or artboard is used in this component. This component can be easily distinguished by overriding the default style rules and…

bulma-datepicker

Versatile Date and Time Picker Calendar for Bulma

Bulma extension for calendar display can be used on a page as a large calendar with appointments or as a date picker/popup window. A responsive, customizable, and…

javascript-time-series-chart-library

Simple Time-Series Chart Viewer with HTML5 Canvas Javascript Library

Pixl chart library displays time series charts in the browser, using the HTML5 Canvas element. It is designed to be lightweight and efficient, while still providing a…

Neumorphic-Design-CSS

Neumorphic Design Inspiration Style CSS Shapes | Neumorphism

Multi-dimensional design is inspired by the physical world and adds textures, reflection, shadows, layers, and depths to the flat design making the UI elements more visible. CSS…