Bootstrap 4 Navbars: Understanding Mobile Collapse

Intro

The documentation for Bootstrap 4 navbars is surprisingly poor when it comes to explaining how the mobile menu collapse works. So today we are going to take a bit of a deep dive into this subject. What exactly do each of these navbar classes do? How do we separate our mobile and desktop menus? Letโ€™s get started.

The <nav> element is not a Bootstrap CSS class. This is a native HTML element. This will be obvious to many, but because it looks so similar to the following CSS classes I thought it was worth mentioning to avoid confusion. This is simply a specific type of <div> wrapper meant to denote that the contents are used for navigation. It imparts no properties of itโ€™s own. This is mostly helpful for screen readers.

This is the first class that will always be added to the <nav> element. It creates a relative position flex container.

<nav class="navbar">
<!-- navbar content -->
</nav>

Here is the class in the Bootstrap CSS file for reference.

.navbar {
  position: relative;
  display: flex;
  flex-wrap: wrap; // allow us to do the line break for collapsing content
  align-items: center;
  justify-content: space-between; // space out brand from logo
  
// etc etc, more in actual code
  }
}

You will see nothing until you add content to this wrapper.

Collapsing

This creates a flex column. The key thing to note is column. So by default our navigation items will display vertically, because Bootstrap is a mobile first framework. Our navigation links will never display horizontally until we add the .navbar-expand- {-sm|-md|-lg|-xl} class to our .navbar wrapper.

<nav class="navbar navbar-light bg-light">
    <div class="navbar-brand">BRAND</div>
    <ul class="navbar-nav">
        <li>Link 1</li>
        <li>Link 2</li>
        <li>Link 3</li>
    </ul>
</nav>
// Navbar nav
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).

.navbar-nav {
  display: flex;
  flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
  
// etc etc ...
  }
}

This is a required class that we add to the .navbar wrapper that decides at what point the menu will change from vertical to horizontal. For example if you select md when the screen hits the medium breakpoint the .navbar-nav content will snap to horizontal.

<nav class="navbar navbar-expand-md navbar-light bg-light">
    <a href="#" class="navbar-brand">BRAND</a>
    <ul class="navbar-nav">
      <li class="nav-item">
        <a href="#" class="nav-link">Link 1</a>
      </li>
      <li class="nav-item">
        <a href="#" class="nav-link">Link 2</a>
      </li>
      <li class="nav-item">
        <a href="#" class="nav-link">Link 3</a>
      </li>
    </ul>
  </nav>

.collapse .navbar-collapse

This is the wrapper that moves content into the collapse (mobile) menu.

It is important to note at this point, that when the screen is smaller than the md breakpoint, the content inside the .collapse .navbar-collapse wrapper will be invisible until you add the .navbar-toggler button. For example:

<nav class="navbar navbar-expand-md navbar-light bg-light">
    <a href="#" class="navbar-brand">BRAND</a>
    <div class="collapse navbar-collapse">
      <ul class="navbar-nav">
        <li class="nav-item">
          <a href="#" class="nav-link">Link 1</a>
        </li>
        <li class="nav-item">
          <a href="#" class="nav-link">Link 2</a>
        </li>
        <li class="nav-item">
          <a href="#" class="nav-link">Link 3</a>
        </li>
      </ul>
    </div>
</nav>

To make the contents inside the collapse wrapper visible, you must include a .navbar-toggler button. You must then link the toggle button to the .collapse .navbar-collapse div with an ID. In this example navbarNav. The hamburger .navbar-toggler-icon is optional.

<nav class="navbar navbar-expand-md navbar-light bg-light">
    <a href="#" class="navbar-brand">BRAND</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNav">
      <ul class="navbar-nav">
        <li class="nav-item">
          <a href="#" class="nav-link">Link 1</a>
        </li>
        <li class="nav-item">
          <a href="#" class="nav-link">Link 2</a>
        </li>
        <li class="nav-item">
          <a href="#" class="nav-link">Link 3</a>
        </li>
      </ul>
    </div>
  </nav>

Creating Different Menus for Mobile Vs Desktop

There may be an instance where you want to create a different menu for mobile vs desktop (or you want the same items styled differently). In this case you can use Bootstrap Display Properties to show or hide items in the nav based on breakpoints, and match those breakpoints to the menu collapse.

<div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
    <li class="nav-item d-none d-md-block">
        <a href="#" class="nav-link">Visible on Medium and larger</a>
    </li>
    <li class="nav-item d-md-none">
        <a href="#" class="nav-link">Visible when smaller than Medium</a>
    </li> 
    </ul>
</div>