DEV Community

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

Posted on

1 1

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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay