Multi-Level Menu

A simple multi-level menu with delayed item animations and an optional breadcrumb navigation and back button.

Blueprint_MutliLevelMenu

View demo Download source

Today’s Blueprint is a simple menu with multiple levels. The idea is to animate each menu item once a level is changed. The animation starts with the item clicked and the delays are propagated through the neighbors. The animation delays follow the same logic for the incoming items of the new level of the multi-level menu. As optional elements we have a breadcrumb navigation and a back button (not shown in our demo). Deeper levels are referenced with a data attribute. We have added some example media queries for a mobile menu version with a menu toggle. We’ve also provided a simple callback example.

The icons used in the demo are from the Organic Food icon set by Wojciech Zasina and the Feather icon set by Cole Bemis.

Please note that we are using a couple of modern CSS properties, so only modern browsers are supported.

Browser Support:
  • ChromeSupported
  • FirefoxSupported
  • Internet ExplorerSupported from version 10+
  • SafariSupported
  • OperaSupported

The HTML

<!-- Main container -->
<div class="container">
	<!-- Menu toggle for mobile version -->
	<button class="action action--open" aria-label="Open Menu"><span class="icon icon--menu"></span></button>
	<!-- Menu -->
	<nav id="ml-menu" class="menu">
		<!-- Close button for mobile version -->
		<button class="action action--close" aria-label="Close Menu"><span class="icon icon--cross"></span></button>
		<div class="menu__wrap">
			<ul data-menu="main" class="menu__level">
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-1" href="#">Vegetables</a></li>
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-2" href="#">Fruits</a></li>
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-3" href="#">Grains</a></li>
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-4" href="#">Mylk & Drinks</a></li>
			</ul>
			<!-- Submenu 1 -->
			<ul data-menu="submenu-1" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Stalk Vegetables</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Roots & Seeds</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Cabbages</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Salad Greens</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Mushrooms</a></li>
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-1-1" href="#">Sale %</a></li>
			</ul>
			<!-- Submenu 1-1 -->
			<ul data-menu="submenu-1-1" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Fair Trade Roots</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Dried Veggies</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Our Brand</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Homemade</a></li>
			</ul>
			<!-- Submenu 2 -->
			<ul data-menu="submenu-2" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Citrus Fruits</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Berries</a></li>
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-2-1" href="#">Special Selection</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Tropical Fruits</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Melons</a></li>
			</ul>
			<!-- Submenu 2-1 -->
			<ul data-menu="submenu-2-1" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Exotic Mixes</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Wild Pick</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Vitamin Boosters</a></li>
			</ul>
			<!-- Submenu 3 -->
			<ul data-menu="submenu-3" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Buckwheat</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Millet</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Quinoa</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Wild Rice</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Durum Wheat</a></li>
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-3-1" href="#">Promo Packs</a></li>
			</ul>
			<!-- Submenu 3-1 -->
			<ul data-menu="submenu-3-1" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Starter Kit</a></li>
				<li class="menu__item"><a class="menu__link" href="#">The Essential 8</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Bolivian Secrets</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Flour Packs</a></li>
			</ul>
			<!-- Submenu 4 -->
			<ul data-menu="submenu-4" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Grain Mylks</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Seed Mylks</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Nut Mylks</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Nutri Drinks</a></li>
				<li class="menu__item"><a class="menu__link" data-submenu="submenu-4-1" href="#">Selection</a></li>
			</ul>
			<!-- Submenu 4-1 -->
			<ul data-menu="submenu-4-1" class="menu__level">
				<li class="menu__item"><a class="menu__link" href="#">Nut Mylk Packs</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Amino Acid Heaven</a></li>
				<li class="menu__item"><a class="menu__link" href="#">Allergy Free</a></li>
			</ul>
		</div>
	</nav>
	<div class="content">
		<p class="info">Please choose a category</p>
		<!-- Ajax loaded content here -->
	</div>
</div>
<!-- /view -->
<script src="js/classie.js"></script>
<script src="js/dummydata.js"></script>
<script src="js/main.js"></script>
<script>
(function() {
	var menuEl = document.getElementById('ml-menu'),
		mlmenu = new MLMenu(menuEl, {
			// breadcrumbsCtrl : true, // show breadcrumbs
			// initialBreadcrumb : 'all', // initial breadcrumb text
			backCtrl : false, // show back button
			// itemsDelayInterval : 60, // delay between each menu item sliding animation
			onItemClick: loadDummyData // callback: item that doesn´t have a submenu gets clicked - onItemClick([event], [inner HTML of the clicked item])
		});

	// mobile menu toggle
	var openMenuCtrl = document.querySelector('.action--open'),
		closeMenuCtrl = document.querySelector('.action--close');

	openMenuCtrl.addEventListener('click', openMenu);
	closeMenuCtrl.addEventListener('click', closeMenu);

	function openMenu() {
		classie.add(menuEl, 'menu--open');
	}

	function closeMenu() {
		classie.remove(menuEl, 'menu--open');
	}

	// simulate grid content loading
	var gridWrapper = document.querySelector('.content');

	function loadDummyData(ev, itemName) {
		ev.preventDefault();

		closeMenu();
		gridWrapper.innerHTML = '';
		classie.add(gridWrapper, 'content--loading');
		setTimeout(function() {
			classie.remove(gridWrapper, 'content--loading');
			gridWrapper.innerHTML = '<ul class="products">' + dummyData[itemName] + '<ul>';
		}, 700);
	}
})();
</script>

The CSS

/* Icons (made with Icomoon.io) */
/* Feather Icons by Cole Bemis */
@font-face {
	font-family: 'feather';
	font-weight: normal;
	font-style: normal;
	src: url('../fonts/feather/feather.eot?1gafuo');
	src: url('../fonts/feather/feather.eot?1gafuo#iefix') format('embedded-opentype'), url('../fonts/feather/feather.woff2?1gafuo') format('woff2'), url('../fonts/feather/feather.ttf?1gafuo') format('truetype'), url('../fonts/feather/feather.woff?1gafuo') format('woff'), url('../fonts/feather/feather.svg?1gafuo#feather') format('svg');
}

.icon {
	font-family: 'feather';
	font-weight: normal;
	font-style: normal;
	font-variant: normal;
	line-height: 1;
	text-transform: none;
	/* Better Font Rendering =========== */
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	speak: none;
}

.icon--arrow-left:before {
	content: '\e901';
}

.icon--menu:before {
	content: '\e903';
}

.icon--cross:before {
	content: '\e117';
} 


/* Menu styles */

.menu {
	position: fixed;
	top: 120px;
	left: 0;
	width: 300px;
	height: calc(100vh - 120px);
	background: #1c1d22;
}

.menu__wrap {
	position: absolute;
	top: 3.5em;
	bottom: 0;
	overflow: hidden;
	width: 100%;
}

.menu__level {
	position: absolute;
	top: 0;
	left: 0;
	visibility: hidden;
	overflow: hidden;
	overflow-y: scroll;
	width: calc(100% + 50px);
	height: 100%;
	margin: 0;
	padding: 0;
	list-style-type: none;
}

.menu__level--current {
	visibility: visible;
}

.menu__item {
	display: block;
	width: calc(100% - 50px);
}

.menu__link {
	font-weight: 600;
	position: relative;
	display: block;
	padding: 1em 2.5em 1em 1.5em;
	color: #bdbdbd;
	-webkit-transition: color 0.1s;
	transition: color 0.1s;
}

.menu__link[data-submenu]::after {
	content: '\e904';
	font-family: 'feather';
	position: absolute;
	right: 0;
	padding: 0.25em 1.25em;
	color: #2a2b30;
}

.menu__link:hover,
.menu__link[data-submenu]:hover::after {
	color: #5c5edc;
}

.menu__link--current::before {
	content: '\00B7';
	font-size: 1.5em;
	line-height: 0;
	position: absolute;
	top: 50%;
	left: 0.5em;
	height: 4px;
	color: #5c5edc;
}

[class^='animate-'],
[class*=' animate-'] {
	visibility: visible;
}

.animate-outToRight .menu__item {
	-webkit-animation: outToRight 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
	animation: outToRight 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
}

@-webkit-keyframes outToRight {
	to {
		opacity: 0;
		-webkit-transform: translate3d(100%, 0, 0);
		transform: translate3d(100%, 0, 0);
	}
}

@keyframes outToRight {
	to {
		opacity: 0;
		-webkit-transform: translate3d(100%, 0, 0);
		transform: translate3d(100%, 0, 0);
	}
}

.animate-outToLeft .menu__item {
	-webkit-animation: outToLeft 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
	animation: outToLeft 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
}

@-webkit-keyframes outToLeft {
	to {
		opacity: 0;
		-webkit-transform: translate3d(-100%, 0, 0);
		transform: translate3d(-100%, 0, 0);
	}
}

@keyframes outToLeft {
	to {
		opacity: 0;
		-webkit-transform: translate3d(-100%, 0, 0);
		transform: translate3d(-100%, 0, 0);
	}
}

.animate-inFromLeft .menu__item {
	-webkit-animation: inFromLeft 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
	animation: inFromLeft 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
}

@-webkit-keyframes inFromLeft {
	from {
		opacity: 0;
		-webkit-transform: translate3d(-100%, 0, 0);
		transform: translate3d(-100%, 0, 0);
	}
	to {
		opacity: 1;
		-webkit-transform: translate3d(0, 0, 0);
		transform: translate3d(0, 0, 0);
	}
}

@keyframes inFromLeft {
	from {
		opacity: 0;
		-webkit-transform: translate3d(-100%, 0, 0);
		transform: translate3d(-100%, 0, 0);
	}
	to {
		opacity: 1;
		-webkit-transform: translate3d(0, 0, 0);
		transform: translate3d(0, 0, 0);
	}
}

.animate-inFromRight .menu__item {
	-webkit-animation: inFromRight 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
	animation: inFromRight 0.6s both cubic-bezier(0.7, 0, 0.3, 1);
}

@-webkit-keyframes inFromRight {
	from {
		opacity: 0;
		-webkit-transform: translate3d(100%, 0, 0);
		transform: translate3d(100%, 0, 0);
	}
	to {
		opacity: 1;
		-webkit-transform: translate3d(0, 0, 0);
		transform: translate3d(0, 0, 0);
	}
}

@keyframes inFromRight {
	from {
		opacity: 0;
		-webkit-transform: translate3d(100%, 0, 0);
		transform: translate3d(100%, 0, 0);
	}
	to {
		opacity: 1;
		-webkit-transform: translate3d(0, 0, 0);
		transform: translate3d(0, 0, 0);
	}
}

.menu__breadcrumbs {
	font-size: 0.65em;
	line-height: 1;
	position: relative;
	padding: 2.5em 3.75em 1.5em 2.5em;
}

.menu__breadcrumbs a {
	font-weight: bold;
	display: inline-block;
	cursor: pointer;
	vertical-align: middle;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: #5c5edc;
}

.menu__breadcrumbs a:last-child {
	pointer-events: none;
}

.menu__breadcrumbs a:hover {
	color: #8182e0;
}

.menu__breadcrumbs a:not(:last-child)::after {
	content: '\e902';
	font-family: 'feather';
	display: inline-block;
	padding: 0 0.5em;
	color: #33353e;
}

.menu__breadcrumbs a:not(:last-child):hover::after {
	color: #33353e;
}

.menu__back {
	font-size: 1.05em;
	position: absolute;
	z-index: 100;
	top: 0;
	right: 2.25em;
	margin: 0;
	padding: 1.365em 0.65em 0 0;
	cursor: pointer;
	color: #2a2b30;
	border: none;
	background: none;
}

.menu__back--hidden {
	pointer-events: none;
	opacity: 0;
}

.menu__back:hover,
.menu__back:focus {
	color: #fff;
	outline: none;
}


/* Open and close buttons */

.action {
	position: absolute;
	display: block;
	margin: 0;
	padding: 0;
	cursor: pointer;
	border: none;
	background: none;
}

.action:focus {
	outline: none;
}

.action--open {
	font-size: 1.5em;
	top: 1em;
	left: 1em;
	display: none;
	color: #fff;
	position: fixed;
	z-index: 1000;
}

.action--close {
	font-size: 1.1em;
	top: 1.25em;
	right: 1em;
	display: none;
	color: #45464e;
}

/* Example media query */
@media screen and (max-width: 40em) {
	.action--open,
	.action--close {
		display: block;
	}
	.menu {
		z-index: 1000;
		top: 0;
		width: 100%;
		height: 100vh;
		-webkit-transform: translate3d(-100%, 0, 0);
		transform: translate3d(-100%, 0, 0);
		-webkit-transition: -webkit-transform 0.3s;
		transition: transform 0.3s;
	}
	.menu--open {
		-webkit-transform: translate3d(0, 0, 0);
		transform: translate3d(0, 0, 0);
	}
}

The JavaScript

/**
 * main.js
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2015, Codrops
 * http://www.codrops.com
 */
;(function(window) {

	'use strict';

	var support = { animations : Modernizr.cssanimations },
		animEndEventNames = { 'WebkitAnimation' : 'webkitAnimationEnd', 'OAnimation' : 'oAnimationEnd', 'msAnimation' : 'MSAnimationEnd', 'animation' : 'animationend' },
		animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ],
		onEndAnimation = function( el, callback ) {
			var onEndCallbackFn = function( ev ) {
				if( support.animations ) {
					if( ev.target != this ) return;
					this.removeEventListener( animEndEventName, onEndCallbackFn );
				}
				if( callback && typeof callback === 'function' ) { callback.call(); }
			};
			if( support.animations ) {
				el.addEventListener( animEndEventName, onEndCallbackFn );
			}
			else {
				onEndCallbackFn();
			}
		};

	function extend( a, b ) {
		for( var key in b ) { 
			if( b.hasOwnProperty( key ) ) {
				a[key] = b[key];
			}
		}
		return a;
	}

	function MLMenu(el, options) {
		this.el = el;
		this.options = extend( {}, this.options );
		extend( this.options, options );
		
		// the menus (
    ´s) this.menus = [].slice.call(this.el.querySelectorAll('.menu__level')); // index of current menu this.current = 0; this._init(); } MLMenu.prototype.options = { // show breadcrumbs breadcrumbsCtrl : true, // initial breadcrumb text initialBreadcrumb : 'all', // show back button backCtrl : true, // delay between each menu item sliding animation itemsDelayInterval : 60, // direction direction : 'r2l', // callback: item that doesn´t have a submenu gets clicked // onItemClick([event], [inner HTML of the clicked item]) onItemClick : function(ev, itemName) { return false; } }; MLMenu.prototype._init = function() { // iterate the existing menus and create an array of menus, more specifically an array of objects where each one holds the info of each menu element and its menu items this.menusArr = []; var self = this; this.menus.forEach(function(menuEl, pos) { var menu = {menuEl : menuEl, menuItems : [].slice.call(menuEl.querySelectorAll('.menu__item'))}; self.menusArr.push(menu); // set current menu class if( pos === self.current ) { classie.add(menuEl, 'menu__level--current'); } }); // create back button if( this.options.backCtrl ) { this.backCtrl = document.createElement('button'); this.backCtrl.className = 'menu__back menu__back--hidden'; this.backCtrl.setAttribute('aria-label', 'Go back'); this.backCtrl.innerHTML = ''; this.el.insertBefore(this.backCtrl, this.el.firstChild); } // create breadcrumbs if( self.options.breadcrumbsCtrl ) { this.breadcrumbsCtrl = document.createElement('nav'); this.breadcrumbsCtrl.className = 'menu__breadcrumbs'; this.el.insertBefore(this.breadcrumbsCtrl, this.el.firstChild); // add initial breadcrumb this._addBreadcrumb(0); } // event binding this._initEvents(); }; MLMenu.prototype._initEvents = function() { var self = this; for(var i = 0, len = this.menusArr.length; i < len; ++i) { this.menusArr[i].menuItems.forEach(function(item, pos) { item.querySelector('a').addEventListener('click', function(ev) { var submenu = ev.target.getAttribute('data-submenu'), itemName = ev.target.innerHTML, subMenuEl = self.el.querySelector('ul[data-menu="' + submenu + '"]'); // check if there's a sub menu for this item if( submenu && subMenuEl ) { ev.preventDefault(); // open it self._openSubMenu(subMenuEl, pos, itemName); } else { // add class current var currentlink = self.el.querySelector('.menu__link--current'); if( currentlink ) { classie.remove(self.el.querySelector('.menu__link--current'), 'menu__link--current'); } classie.add(ev.target, 'menu__link--current'); // callback self.options.onItemClick(ev, itemName); } }); }); } // back navigation if( this.options.backCtrl ) { this.backCtrl.addEventListener('click', function() { self._back(); }); } }; MLMenu.prototype._openSubMenu = function(subMenuEl, clickPosition, subMenuName) { if( this.isAnimating ) { return false; } this.isAnimating = true; // save "parent" menu index for back navigation this.menusArr[this.menus.indexOf(subMenuEl)].backIdx = this.current; // save "parent" menu´s name this.menusArr[this.menus.indexOf(subMenuEl)].name = subMenuName; // current menu slides out this._menuOut(clickPosition); // next menu (submenu) slides in this._menuIn(subMenuEl, clickPosition); }; MLMenu.prototype._back = function() { if( this.isAnimating ) { return false; } this.isAnimating = true; // current menu slides out this._menuOut(); // next menu (previous menu) slides in var backMenu = this.menusArr[this.menusArr[this.current].backIdx].menuEl; this._menuIn(backMenu); // remove last breadcrumb if( this.options.breadcrumbsCtrl ) { this.breadcrumbsCtrl.removeChild(this.breadcrumbsCtrl.lastElementChild); } }; MLMenu.prototype._menuOut = function(clickPosition) { // the current menu var self = this, currentMenu = this.menusArr[this.current].menuEl, isBackNavigation = typeof clickPosition == 'undefined' ? true : false; // slide out current menu items - first, set the delays for the items this.menusArr[this.current].menuItems.forEach(function(item, pos) { item.style.WebkitAnimationDelay = item.style.animationDelay = isBackNavigation ? parseInt(pos * self.options.itemsDelayInterval) + 'ms' : parseInt(Math.abs(clickPosition - pos) * self.options.itemsDelayInterval) + 'ms'; }); // animation class if( this.options.direction === 'r2l' ) { classie.add(currentMenu, !isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight'); } else { classie.add(currentMenu, isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight'); } }; MLMenu.prototype._menuIn = function(nextMenuEl, clickPosition) { var self = this, // the current menu currentMenu = this.menusArr[this.current].menuEl, isBackNavigation = typeof clickPosition == 'undefined' ? true : false, // index of the nextMenuEl nextMenuIdx = this.menus.indexOf(nextMenuEl), nextMenuItems = this.menusArr[nextMenuIdx].menuItems, nextMenuItemsTotal = nextMenuItems.length; // slide in next menu items - first, set the delays for the items nextMenuItems.forEach(function(item, pos) { item.style.WebkitAnimationDelay = item.style.animationDelay = isBackNavigation ? parseInt(pos * self.options.itemsDelayInterval) + 'ms' : parseInt(Math.abs(clickPosition - pos) * self.options.itemsDelayInterval) + 'ms'; // we need to reset the classes once the last item animates in // the "last item" is the farthest from the clicked item // let's calculate the index of the farthest item var farthestIdx = clickPosition <= nextMenuItemsTotal/2 || isBackNavigation ? nextMenuItemsTotal - 1 : 0; if( pos === farthestIdx ) { onEndAnimation(item, function() { // reset classes if( self.options.direction === 'r2l' ) { classie.remove(currentMenu, !isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight'); classie.remove(nextMenuEl, !isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft'); } else { classie.remove(currentMenu, isBackNavigation ? 'animate-outToLeft' : 'animate-outToRight'); classie.remove(nextMenuEl, isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft'); } classie.remove(currentMenu, 'menu__level--current'); classie.add(nextMenuEl, 'menu__level--current'); //reset current self.current = nextMenuIdx; // control back button and breadcrumbs navigation elements if( !isBackNavigation ) { // show back button if( self.options.backCtrl ) { classie.remove(self.backCtrl, 'menu__back--hidden'); } // add breadcrumb self._addBreadcrumb(nextMenuIdx); } else if( self.current === 0 && self.options.backCtrl ) { // hide back button classie.add(self.backCtrl, 'menu__back--hidden'); } // we can navigate again.. self.isAnimating = false; }); } }); // animation class if( this.options.direction === 'r2l' ) { classie.add(nextMenuEl, !isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft'); } else { classie.add(nextMenuEl, isBackNavigation ? 'animate-inFromRight' : 'animate-inFromLeft'); } }; MLMenu.prototype._addBreadcrumb = function(idx) { if( !this.options.breadcrumbsCtrl ) { return false; } var bc = document.createElement('a'); bc.innerHTML = idx ? this.menusArr[idx].name : this.options.initialBreadcrumb; this.breadcrumbsCtrl.appendChild(bc); var self = this; bc.addEventListener('click', function(ev) { ev.preventDefault(); // do nothing if this breadcrumb is the last one in the list of breadcrumbs if( !bc.nextSibling || self.isAnimating ) { return false; } self.isAnimating = true; // current menu slides out self._menuOut(); // next menu slides in var nextMenu = self.menusArr[idx].menuEl; self._menuIn(nextMenu); // remove breadcrumbs that are ahead var siblingNode; while (siblingNode = bc.nextSibling) { self.breadcrumbsCtrl.removeChild(siblingNode); } }); }; window.MLMenu = MLMenu; })(window);

View demo Download source

Previous:
Next:

Tagged with:

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.

View all contributions by

Website: http://www.codrops.com

Related Articles

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 61

  1. 1

    How can I get the links to go to html files? I want to integrate with WordPress but when I try to use external links as suggested by @Raymond above, the menu disappears. Anyone had any success with this?

    • 2

      In order to work the external link (the last one with href),just delete the “onItemClick” so: onItemClick: loadDummyData – also the loadDummyData(){…} function.

      P.S – on the demo link “https://tympanus.net/Blueprints/MultiLevelMenu/” the menu works on my iphone 4s, but when I download the source, I click on the menu and it doesn’t open. This is very strange, is there any different script called online (which I dont think so). Any idea ???

  2. 3

    Hey, thanks very much. for this awesome blueprint. I have an urgent request. I tried to use this blueprint as a non-ajax Main-Navigation for a CMS. After figuring out the current page and the related submenu I set the according index to this.current in the JS-File. The according submenu is opening when a subpage is loaded, which is fine, but the breadcrumbs and back controls are not behaving accordingly, because it thinks the opened submenu is the new root-level. I already opened an issue on GitHub, but no answer so far. Any ideas on how to set/open a submenu on initialization?

  3. 4

    This plugin is awesome, but I have problem with crossbrowser test. It says multybrowser support, how I can run on IE10+ and Microsoft Edge. Menu is blank even if I already allow block content.

  4. 5

    Do you really need all that JavaScript ??

    What if I just wanted a menu with different levels could I just use JQuery(Hide/Show/AddClass) etc etc I’m not bothered about the history displaying links either ?

  5. 7

    Maybe you mentioned …,
    How can I change the icon to display div content in html?
    …I’m sorry, I’m not professional
    Thank you
    Michal

Follow this discussion

Leave a Comment