Created
October 10, 2024 14:02
-
-
Save mucavel/937c7d10063002968eca9340c9b76919 to your computer and use it in GitHub Desktop.
Megamenu - Bootstrap 4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<nav class="megamenu"> | |
<ul class="megamenu-nav d-flex justify-content-center" role="menu"> | |
<li class="nav-item"> | |
<a class="nav-link" href="#"> | |
<i class="fa fa-home"></i> | |
<span class="sr-only">Home</span> | |
</a> | |
</li> | |
<li class="nav-item is-parent"> | |
<a class="nav-link" href="#" id="megamenu-dropdown-1" aria-haspopup="true" aria-expanded="false"> | |
Link 1 <i class="fa fa-angle-down"></i> | |
</a> | |
<div class="megamenu-content" aria-labelledby="megamenu-dropdown-1"> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-8 pr-5"> | |
<div class="row"> | |
<div class="col-6"> | |
<h3 class="">Another title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
</ul> | |
</div> | |
<div class="col-6"> | |
<h3 class="">Some title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<hr> | |
<div class="d-flex"> | |
<div class="align-self-center pr-4"> | |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae corrupti reprehenderit provident ipsam quibusdam, iste ad amet exercitationem sunt. Impedit libero aperiam ratione reiciendis dolorem itaque aut quas eos labore. | |
</div> | |
<div class="align-self-center"> | |
<a href="#" class="btn btn-outline-primary">Click me</a> | |
</div> | |
</div> | |
</div> | |
<div class="col-4"> | |
<img src="//placeimg.com/640/480/any" class="img-fluid mb-3" alt="test image"> | |
<p> | |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem, expedita sint quis rem amet, a nihil, non sunt ea quasi. | |
</p> | |
<a href="#">See more <i class="fa fa-angle-double-right"></i></a> | |
</div> | |
</div> | |
</div> | |
</div> | |
</li> | |
<li class="nav-item is-parent"> | |
<a class="nav-link" href="#" id="megamenu-dropdown-2" aria-haspopup="true" aria-expanded="false"> | |
Link 2 <i class="fa fa-angle-down"></i> | |
</a> | |
<div class="megamenu-content" aria-labelledby="megamenu-dropdown-2"> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-8 pr-5"> | |
<div class="row"> | |
<div class="col-6"> | |
<h3 class="">Some title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 4</a> | |
</li> | |
</ul> | |
</div> | |
<div class="col-6"> | |
<h3 class="">Another title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem 2</a> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<hr> | |
<div class="d-flex"> | |
<div class="align-self-center pr-4"> | |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae corrupti reprehenderit provident ipsam quibusdam, iste ad amet exercitationem sunt. Impedit libero aperiam ratione reiciendis dolorem itaque aut quas eos labore. | |
</div> | |
<div class="align-self-center"> | |
<a href="#" class="btn btn-outline-primary">Click me</a> | |
</div> | |
</div> | |
</div> | |
<div class="col-4"> | |
<img src="//placeimg.com/641/430/any" class="img-fluid mb-3" alt="test image"> | |
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem, expedita sint quis rem amet, a nihil, non sunt ea quasi.</p> | |
<a href="#">Read more <i class="fa fa-angle-double-right"></i></a> | |
</div> | |
</div> | |
</div> | |
</div> | |
</li> | |
<li class="nav-item is-parent"> | |
<a class="nav-link" href="#" id="megamenu-dropdown-3" aria-haspopup="true" aria-expanded="false"> | |
Link 3 <i class="fa fa-angle-down"></i> | |
</a> | |
<div class="megamenu-content" aria-labelledby="megamenu-dropdown-3"> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-8 pr-5"> | |
<div class="row"> | |
<div class="col-6"> | |
<h3 class="">Another title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
</ul> | |
</div> | |
<div class="col-6"> | |
<h3 class="">Some title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<hr> | |
<div class="d-flex"> | |
<div class="align-self-center pr-4"> | |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae corrupti reprehenderit provident ipsam quibusdam, iste ad amet exercitationem sunt. Impedit libero aperiam ratione reiciendis dolorem itaque aut quas eos labore. | |
</div> | |
<div class="align-self-center"> | |
<a href="#" class="btn btn-outline-primary">Click me</a> | |
</div> | |
</div> | |
</div> | |
<div class="col-4"> | |
<img src="//placeimg.com/640/480/any" class="img-fluid mb-3" alt="test image"> | |
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem, expedita sint quis rem amet, a nihil, non sunt ea quasi.</p> | |
<a href="#">Read more <i class="fa fa-angle-double-right"></i></a> | |
</div> | |
</div> | |
</div> | |
</div> | |
</li> | |
<li class="nav-item is-parent"> | |
<a class="nav-link" href="#" id="megamenu-dropdown-4" aria-haspopup="true" aria-expanded="false"> | |
Link 4 <i class="fa fa-angle-down"></i> | |
</a> | |
<div class="megamenu-content" aria-labelledby="megamenu-dropdown-4"> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-8 pr-5"> | |
<div class="row"> | |
<div class="col-6"> | |
<h3 class="">Some title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 4</a> | |
</li> | |
</ul> | |
</div> | |
<div class="col-6"> | |
<h3 class="">Another title</h3> | |
<hr> | |
<ul class="subnav"> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 1</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Menuitem 3</a> | |
</li> | |
<li class="subnav-item"> | |
<a href="#" class="subnav-link">Another menuitem 2</a> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<hr> | |
<div class="d-flex"> | |
<div class="align-self-center pr-4"> | |
Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae corrupti reprehenderit provident ipsam quibusdam, iste ad amet exercitationem sunt. Impedit libero aperiam ratione reiciendis dolorem itaque aut quas eos labore. | |
</div> | |
<div class="align-self-center"> | |
<a href="#" class="btn btn-outline-primary">Click me</a> | |
</div> | |
</div> | |
</div> | |
<div class="col-4"> | |
<img src="//placeimg.com/641/430/any" class="img-fluid mb-3" alt="test image"> | |
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Autem, expedita sint quis rem amet, a nihil, non sunt ea quasi.</p> | |
<a href="#">Read more <i class="fa fa-angle-double-right"></i></a> | |
</div> | |
</div> | |
</div> | |
</div> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="#"> | |
Link without megamenu | |
</a> | |
</li> | |
</ul> | |
<div class="megamenu-background" id="megamenu-background"></div> | |
</nav> | |
<div class="megamenu-dim" id="megamenu-dim"></div> | |
<section class="hero"> | |
<div class="container pt-4"> | |
<h1 class="display-2 mb-4">Megamenu</h1> | |
<p class="lead"> | |
Dependencies are: <strong>Bootstrap 4, jQuery, jQuery.hoverIntent, Lodash (debounce and throttle)</strong> | |
</p> | |
<p class="lead"><em>Should work quite well™ </em>with mouse hover, clicks/keyboard and touch devices.</p> | |
<p class="lead">Hover Intent plugin is used to track user mouse movement and not fire the megamenu event if cursor is moved rapidly over the main menu elements.</p> | |
<p class="lead">Adjusts the menu background height automatically when resizing the browser window. Calculates menu background height from the tallest megamenu content.</p> | |
<p class="lead">Missing responsive styling :(</p> | |
</div> | |
</section> | |
<section class="bg-light"> | |
<div class="container"> | |
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nesciunt cumque hic ipsam et. Perferendis voluptatum incidunt maxime eos et officiis exercitationem! Expedita ipsa tenetur porro dolores possimus cum ab sapiente.</p> | |
</div> | |
</section> | |
<section class="bg-white"> | |
<div class="container"> | |
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Nesciunt cumque hic ipsam et. Perferendis voluptatum incidunt maxime eos et officiis exercitationem! Expedita ipsa tenetur porro dolores possimus cum ab sapiente.</p> | |
</div> | |
</section> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const $megamenuParentListItem = $('.megamenu-nav > li.is-parent'); | |
const $megamenuBackground = $('#megamenu-background'); | |
const isTouch = 'ontouchstart' in window || !!(navigator.msMaxTouchPoints); | |
const handleMenuItemOpenState = (elem) => { | |
elem.addClass('is-open'); | |
elem.find('a').first().attr('aria-expanded', true); | |
}; | |
const handleMenuItemCloseState = (elem) => { | |
elem.removeClass('is-open'); | |
elem.find('a').first().attr('aria-expanded', false); | |
}; | |
const openMegamenu = (bgElem, heightVal) => { | |
$('body').addClass('megamenu-visible'); | |
bgElem.height(heightVal); | |
}; | |
const closeMegamenu = (bgElem, heightVal) => { | |
$('body').removeClass('megamenu-visible'); | |
bgElem.height(heightVal); | |
}; | |
const $megamenuContentElem = $('.megamenu-nav .megamenu-content'); | |
const getTallestMenuHeight = () => { | |
let maxHeight = 0; | |
$megamenuContentElem.each((index, item) => { | |
if ($(item).outerHeight() > maxHeight) { | |
maxHeight = $(item).outerHeight(); | |
} | |
}); | |
return maxHeight; | |
} | |
const debouncedClose = _.debounce(closeMegamenu, 400); | |
const throttledContentHeightCount = _.throttle(getTallestMenuHeight, 100); | |
let megamenuContentMaxHeight = 0; | |
window.onresize = () => { | |
megamenuContentMaxHeight = throttledContentHeightCount(); | |
}; | |
$(() => { | |
megamenuContentMaxHeight = getTallestMenuHeight(); | |
$megamenuParentListItem.each((index, item) => { | |
if (!isTouch) { | |
$(item).hoverIntent({ | |
sensitivity: 10, | |
interval: 50, | |
over: () => { | |
debouncedClose.cancel(); | |
$megamenuParentListItem.removeClass('is-open'); | |
handleMenuItemOpenState($(item)); | |
openMegamenu($megamenuBackground, megamenuContentMaxHeight); | |
}, | |
out: () => { | |
handleMenuItemCloseState($(item)); | |
debouncedClose($megamenuBackground, 0); | |
}, | |
}); | |
} | |
$(item).find('a').first().on('click touch', () => { | |
if (!$(item).hasClass('is-open')) { | |
$megamenuParentListItem.removeClass('is-open'); | |
handleMenuItemOpenState($(item)); | |
openMegamenu($megamenuBackground, megamenuContentMaxHeight); | |
} else { | |
handleMenuItemCloseState($(item)); | |
closeMegamenu($megamenuBackground, 0); | |
} | |
}); | |
}); | |
$('#megamenu-dim').on('click touch', (e) => { | |
if ($('body').hasClass('megamenu-visible')) { | |
e.preventDefault(); | |
$megamenuParentListItem.removeClass('is-open'); | |
closeMegamenu($megamenuBackground, 0); | |
} | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.hoverintent/1.9.0/jquery.hoverIntent.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$body-bg: #fff; | |
$nav-bg: #007bff; | |
$z-index-navbar: 15; | |
$z-index-megamenu-content: $z-index-navbar - 1; | |
$z-index-megamenu-bg: $z-index-megamenu-content - 1; | |
$z-index-megamenu-dim: $z-index-megamenu-bg - 1; | |
$navbar-height: 54px; | |
body { | |
background: $body-bg; | |
} | |
section { | |
padding: 100px 0; | |
} | |
.hero { | |
color: #fff; | |
background-image: url(//placeimg.com/1500/600/any); | |
background-repeat: no-repeat; | |
background-size: cover; | |
position: relative; | |
&:before { | |
content: ""; | |
background: rgba(0,0,0,0.6); | |
position: absolute; | |
left: 0; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
} | |
.container { | |
position: relative; | |
z-index: 2; | |
} | |
} | |
.megamenu { | |
background: $nav-bg; | |
z-index: $z-index-navbar; | |
.megamenu-nav { | |
padding: 0; | |
margin: 0; | |
.nav-item { | |
display: block; | |
&.is-open { | |
> .megamenu-content { | |
visibility: visible; | |
opacity: 1; | |
} | |
> .nav-link { | |
background: #fff; | |
color: #333; | |
} | |
} | |
} | |
.nav-link { | |
color: #fff; | |
padding: 15px 30px; | |
&:hover { | |
background: #fff; | |
color: #333; | |
} | |
} | |
} | |
.megamenu-content { | |
position: absolute; | |
left: 0; | |
right: 0; | |
top: $navbar-height; | |
overflow: hidden; | |
visibility: hidden; | |
opacity: 0; | |
z-index: $z-index-megamenu-content; | |
transition: all .3s ease-in-out; | |
.container { | |
padding: 45px 15px; | |
} | |
.subnav { | |
margin: 0; | |
padding: 0; | |
} | |
.subnav-item { | |
display: block; | |
.subnav-link { | |
padding: 10px 0; | |
display: block; | |
} | |
} | |
} | |
} | |
.megamenu-background { | |
background: #fff; | |
position: absolute; | |
left: 0; | |
top: $navbar-height; | |
right: 0; | |
height: 0; | |
transition: all .3s ease-in-out; | |
box-shadow: 0px 10px 20px rgba(0,0,0,0.15); | |
z-index: $z-index-megamenu-bg; | |
} | |
.megamenu-dim { | |
background: rgba(0,0,0,0.6); | |
position: fixed; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
top: $navbar-height; | |
visibility: hidden; | |
opacity: 0; | |
z-index: -$z-index-megamenu-dim; | |
transition: all .3s ease-in-out; | |
body.megamenu-visible & { | |
z-index: $z-index-megamenu-dim; | |
visibility: visible; | |
opacity: 1; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" /> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment