Megamenu
Megamenu
HTML Source Code
<div role="menubar">
<!-- role="group" -->
<ul id="mega-menu" role="presentation" >
<li id="home" role="presentation"><a href="#" role="menuitem" aria-setsize="5" aria-posinset="1"><i class="fa fa-home"></i>Home</a></li>
<li id="about" class="has-drop" role="presentation"><a href="#" role="menuitem" aria-haspopup="true" aria-setsize="5" aria-posinset="2"><i class="fa fa-users"></i>About<i class="fa fa-toggle-down fa-1"></i></a>
<div class="droplet">
<div role="group" aria-labelledby="about-head-a1" class="col">
<h2 id="about-head-a1" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 1</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 2</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 3</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 4</a></li>
</ul>
</div>
<div role="group" aria-labelledby="about-head-a2" class="col">
<h2 id="about-head-a2" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 5</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 6</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 7</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 8</a></li>
</ul>
</div>
<div role="group" aria-labelledby="about-head-a3" class="col">
<h2 id="about-head-a3" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 9</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 10</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 11</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 12</a></li>
</ul>
</div>
</div>
</li>
<li id="contact" class="has-drop"><a href="#" role="menuitem" aria-haspopup="true" aria-setsize="5" aria-posinset="3"><i class="fa fa-smile-o"></i>Contact<i class="fa fa-toggle-down fa-1"></i></a>
<div class="droplet">
<div role="group" aria-labelledby="about-head-b1" class="col">
<h2 id="about-head-b1" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 1</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 2</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 3</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 4</a></li>
</ul>
</div>
<div role="group" aria-labelledby="about-head-b2" class="col">
<h2 id="about-head-b2" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 5</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 6</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 7</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 8</a></li>
</ul>
</div>
<div role="group" aria-labelledby="about-head-b3" class="col">
<h2 id="about-head-b3" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 9</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 10</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 11</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 12</a></li>
</ul>
</div>
</div>
</li>
<li id="faqs" class="has-drop"><a href="#" role="menuitem" aria-haspopup="true" aria-setsize="5" aria-posinset="4"><i class="fa fa-question-circle"></i>FAQs<i class="fa fa-toggle-down fa-1"></i></a>
<div class="droplet">
<div role="group" aria-labelledby="about-head-c1" class="col">
<h2 id="about-head-c1" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 1</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 2</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 3</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 4</a></li>
</ul>
</div>
<div role="group" aria-labelledby="about-head-c2" class="col">
<h2 id="about-head-c2" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 5</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 6</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 7</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 8</a></li>
</ul>
</div>
<div role="group" aria-labelledby="about-head-c3" class="col">
<h2 id="about-head-c3" class="col-head">Heading</h2>
<ul>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="1">Item 9</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="2">Item 10</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="3">Item 11</a></li>
<li role="presentation"><a href="#" role="menuitem" aria-setsize="4" aria-posinset="4">Item 12</a></li>
</ul>
</div>
</div>
</li>
<li id="links" role="presentation"><a href="#" role="menuitem" aria-setsize="5" aria-posinset="5"><i class="fa fa-external-link"></i>Links</a></li>
</ul>
</div>
JavaScript Source Code
Dependencies:
- JQuery
function initMegaMenu() {
var megaMenu = document.getElementById('mega-menu');
// keyboard stuff
$(megaMenu).delegate('li a', 'keydown', keyboardHandler);
// mouse stuff
$(' > li.has-drop', megaMenu).each(function () {
var dropdown = $('.droplet', $(this)[0]);
$(this).hover(
function () {
$(this).addClass('active');
$('.droplet', megaMenu).each(function (index, drop) {
if (drop !== dropdown) {
$(drop).hide();
}
});
$(dropdown).slideDown(100);
}, function () {
$(this).removeClass('active');
$(dropdown).slideUp(100);
}
);
});
}
function keyboardHandler(keyVent) {
var target = keyVent.target;
var which = keyVent.which;
if (which === 39) { // RIGHT
if (isTopLevel(target)) {
// top level item
var nextTopItem = adjacentTopLevelItem(target, 'next');
if (nextTopItem) {
keyVent.preventDefault();
nextTopItem.focus();
}
} else {
// dropdown item
var nextDropletItem = adjacentDropdownItem(target, 'next');
if (nextDropletItem) {
keyVent.preventDefault();
nextDropletItem.focus();
}
}
} else if (which === 37) { // LEFT
if (isTopLevel(target)) {
// top level item
var prevTopItem = adjacentTopLevelItem(target, 'prev');
if (prevTopItem) {
keyVent.preventDefault();
prevTopItem.focus();
}
} else {
// dropdown item
var prevDropItem = adjacentDropdownItem(target, 'prev');
if (prevDropItem) {
keyVent.preventDefault();
prevDropItem.focus();
}
}
} else if (which === 40) { // DOWN
if (isTopLevel(target) && hasDropdown(target)) {
// top level item w/ dropdown -- open dropdown
openDropdown(target);
} else {
// dropdown item
var nextDropItem = adjacentDropdownItem(target, 'next');
if (nextDropItem) {
keyVent.preventDefault();
nextDropItem.focus();
}
}
} else if (which === 38) { // UP
if (!isTopLevel(target)) {
if (isFirstDropItem(target)) {
keyVent.preventDefault();
var top = closeDropdown(target);
setTimeout(function () {
top.focus();
}, 0);
} else {
var prevDropAnchor = adjacentDropdownItem(target, 'prev');
if (prevDropAnchor) {
keyVent.preventDefault();
prevDropAnchor.focus();
}
}
}
} else if (which === 27) { // ESCAPE
if (!isTopLevel(target)) {
var topper = closeDropdown(target);
setTimeout(function () {
topper.focus();
}, 0);
}
} else if (which === 9 && keyVent.shiftKey) { // SHIFT + TAB
if (!isTopLevel(target) && isFirstDropItem(target)) {
keyVent.preventDefault();
var topA = closeDropdown(target);
setTimeout(function () {
topA.focus();
}, 0);
}
} else if (which === 9) { // TAB
if (!isTopLevel(target) && isLastDropItem(target)) {
keyVent.preventDefault();
var topItem = closeDropdown(target);
var nextLi = $(topItem.parentNode).next()[0];
var nextAnchor = $('a', nextLi)[0];
nextAnchor.focus();
}
} else if (which === 13 || which === 32) {
if (isTopLevel(target) && $(target.parentNode).hasClass('has-drop')) {
openDropdown(target);
}
}
}
// determines if the item is a top-level one
function isTopLevel(item) {
return $(item).is('#mega-menu > li > a');
}
// determines if the item has a dropdown
function hasDropdown(item) {
return $(item.parentNode).hasClass('has-drop');
}
// determines if the item is the first in the dropdown
function isFirstDropItem(item) {
var drop = $(item).closest('.droplet')[0];
var firstInDrop = $('li a', drop)[0];
return firstInDrop === item;
}
// determines if the item is the last in the dropdown
function isLastDropItem(item) {
var drop = $(item).closest('.droplet')[0];
var lastInDrop = $('li a', drop).last()[0];
return lastInDrop === item;
}
// finds the adjacent top level item
function adjacentTopLevelItem(item, dir) {
var li = item.parentNode; // <li />
var adjacentLi = (dir === 'next') ?
$(li).next()[0] :
$(li).prev()[0];
var adjacentItem = adjacentLi && $('a', adjacentLi)[0];
return adjacentItem;
}
// finds the next or prev dropdown item
function adjacentDropdownItem(item, dir) {
var adjacentDropItem;
var li = item.parentNode;
var adjacentSameCol = (dir === 'next') ?
$(li).next()[0] :
$(li).prev()[0];
if (adjacentSameCol) {
// there is one in the same col
adjacentDropItem = $('a', adjacentSameCol)[0];
} else {
// lets look for one in the adjacent column
var col = $(li).closest('.col')[0];
var adjacentCol = (dir === 'next') ?
$(col).next()[0] :
$(col).prev()[0];
if (adjacentCol) {
// we've found the adjacent column
var adjacentItem = (dir === 'next') ?
$('li a', adjacentCol)[0] :
$('li a', adjacentCol).last()[0];
if (adjacentItem) {
adjacentDropItem = adjacentItem;
}
}
}
return adjacentDropItem;
}
function openDropdown(item) {
$(item.parentNode).addClass('active');
var droplet = $(item).next()[0];
// open the dropdown...
$(droplet).slideDown(100);
// ...and focus the first item
setTimeout(function () {
$('a', droplet)[0].focus();
}, 100);
}
function closeDropdown(item) {
var droplet = $(item).closest('.droplet')[0];
var topLevelItem = $(droplet).prev()[0];
$(topLevelItem.parentNode).removeClass('active');
$(droplet).slideUp(100);
return topLevelItem;
}
////////////////////////////////////
$(document).ready(initMegaMenu);
////////////////////////////////////
CSS Source Code
#mega-menu {
margin: 0 auto;
text-align: center;
}
.fa {
margin-right: 5px;
}
.fa.fa-toggle-down {
margin-left: 20px;
}
#mega-menu *:focus {
outline: 4px solid #104BA9;
}
#mega-menu > li.has-drop.active > a {
background-color: #fff;
color: #104BA9;
}
#mega-menu .droplet {
display: none;
font-size: 14px;
outline: 3px solid #ccc;
position: absolute;
background-color:#fff;
}
h2.col-head {
margin: 1px;
padding: 0;
text-decoration: underline;
}
#mega-menu .droplet .col {
display: inline-block;
background-color:#fff;
vertical-align: top;
margin: 0 auto;
padding: 10px;
text-align: center;
}
#mega-menu .droplet .col ul {
padding: 5px;
margin: 0 auto;
list-style-type: none;
}
#mega-menu .droplet .col a {
display: block;
color: #000;
margin: 0;
padding: 0;
}
#mega-menu .droplet .col a:focus,
#mega-menu .droplet .col a:hover {
background-color: #104BA9;
color: #fff;
}
#mega-menu > li {
list-style-type: none;
display: inline-block;
margin: 5px;
}
#mega-menu > li > a {
position: relative;
display: block;
font-size: 14px;
text-align: center;
width: 135px;
padding: 7px;
background-color: #ccc;
text-decoration: none;
color: #000;
}
#mega-menu > li > a:focus,
#mega-menu > li > a:hover {
color: #104BA9;
background-color: #fff;
}