DEV Community

Cover image for Bootstrap 4 Self-collapsing Navbar
Tom Michew for Codeply

Posted on

Bootstrap 4 Self-collapsing Navbar

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!

Demo | Source

Top comments (0)