Bootstrap 4 has a nice responsive Navbar with 5 different breakpoint options. However, when there are many menu items, none of the responsive breakpoints are ideal, and the Navbar items start to wrap which doesn’t look very good 😏.
Here is an alternative responsive Navbar that auto-magically 😎 collapses (as the viewport is resized) the extra overflowing menu items into a Dropdown menu. This implementation is with jQuery, but this JavaScript logic could just as easily be implemented as a Vue, React or Angular component.
Here’s the basic logic:
If the Navbar height is larger than it’s container, the menu items have wrapped and therefore we ADD items to the dropdown
Otherwise, we REMOVE items from the dropdown and return them to the Navbar
We check the above logic when the DOM is loaded, and while the window is resized.
jQuery Logic (could use plain JS instead)
var autocollapse = function (menu,maxHeight) {
var nav = $(menu);
var navHeight = nav.innerHeight();
if (navHeight >= maxHeight) {
$(menu + ' .dropdown').removeClass('d-none');
$(".navbar-nav").removeClass('w-auto').addClass("w-100");
while (navHeight > maxHeight) {
// add child to dropdown
var children = nav.children(menu + ' li:not(:last-child)');
var count = children.length;
$(children[count - 1]).prependTo(menu + ' .dropdown-menu');
navHeight = nav.innerHeight();
}
$(".navbar-nav").addClass("w-auto").removeClass('w-100');
}
else {
var collapsed = $(menu + ' .dropdown-menu').children(menu + ' li');
if (collapsed.length===0) {
$(menu + ' .dropdown').addClass('d-none');
}
while (navHeight < maxHeight && (nav.children(menu + ' li').length > 0) && collapsed.length > 0) {
// remove child from dropdown
collapsed = $(menu + ' .dropdown-menu').children('li');
$(collapsed[0]).insertBefore(nav.children(menu + ' li:last-child'));
navHeight = nav.innerHeight();
}
if (navHeight > maxHeight) {
autocollapse(menu,maxHeight);
}
}
}
$(document).ready(function () {
// when the page loads
autocollapse('#nav',50);
// when the window is resized
$(window).on('resize', function () {
autocollapse('#nav',50);
});
})
HTML Markup
The Navbar markup is the standard Bootstrap 4 responsive Navbar with all of the Navbar Items and a Dropdown on the right.
<nav class="navbar navbar-expand navbar-dark bg-info">
<div class="container-fluid">
<a class="navbar-brand pb-2" href="#">Bootstrap 4</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNavDropdown">
<ul class="navbar-nav align-self-end" id="nav">
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Item 4</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Item 5</a>
</li>
...
<li class="nav-item">
<a class="nav-link" href="#">Item 13</a>
</li>
<li class="nav-item dropdown d-none">
<a class="nav-link" href="#" id="navbarDropdownMenu" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="navbar-toggler-icon"></span>
</a>
<ul class="dropdown-menu dropdown-menu-right bg-info" aria-labelledby="navbarDropdownMenu">
</ul>
</li>
</ul>
</div>
</div>
</nav>
Thanks for reading!
Top comments (0)