No Time Dad

A blog about web development written by a busy dad

Bootstrap Nav Dropdown Example

It feels strange using Bootstrap so much recently. Not in a bad way, just different. I still like writing vanilla css and using Tailwindcss, but there are things that Bootstrap has out of the box that make it appealing. One of those things is dropdown menus.

Dropdown menus are notoriously difficult to implement correctly. By correctly I mean functional and accessible. The latter being the most important, and also the most often overlooked. Bootstrap’s dropdown isn’t the most exciting to look at, but it works well without me having to think about it too much and it’s easy to customize.

bootstrap-nav-dropdown

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <!-- Bootstrap CDN files -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU"
      crossorigin="anonymous"
    />
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ"
      crossorigin="anonymous"
    ></script>

    <title>Dashboard</title>
  </head>
  <body>
    <!-- Start of header -->
    <header>
      <div class="container d-flex align-items-center">
        <!-- Header text -->
        <a href="#home" class="text-decoration-none text-dark">
          <span class="fs-4">bored.io</span>
        </a>

        <!-- Navigvation links -->
        <nav>
          <ul class="nav ms-3">
            <!-- Nav driopdown 1 -->
            <li class="nav-item border-bottom border-2 border-primary">
              <div class="dropdown">
                <button
                  class="btn dropdown-toggle"
                  type="button"
                  data-bs-toggle="dropdown"
                  aria-expanded="false"
                >
                  Dashboard
                </button>
                <ul class="dropdown-menu">
                  <li>
                    <button class="dropdown-item" type="button">Feed</button>
                  </li>
                  <li>
                    <button class="dropdown-item" type="button">
                      Analytics
                    </button>
                  </li>
                  <li>
                    <button class="dropdown-item" type="button">Revenue</button>
                  </li>
                </ul>
              </div>
            </li>

            <!-- Nav dropdown 2 -->
            <li class="nav-item">
              <div class="dropdown">
                <button
                  class="btn dropdown-toggle"
                  type="button"
                  data-bs-toggle="dropdown"
                  aria-expanded="false"
                >
                  Settings
                </button>
                <ul class="dropdown-menu">
                  <li>
                    <button class="dropdown-item" type="button">Profile</button>
                  </li>
                  <li>
                    <button class="dropdown-item" type="button">
                      Connections
                    </button>
                  </li>
                </ul>
              </div>
            </li>
          </ul>
        </nav>
      </div>
    </header>

    <!-- Content section of the page -->
    <main class="container">Content</main>
  </body>
</html>

For this Bootstrap nav dropdown example I really just need a couple dropdown menus with a few links. Nothing too fancy, it just needs to work. I’ll customize it later as needed. Which I think is where Bootstrap shines.

Bootstrap defaults look decent enough and allows me to build rapid prototypes without having to think about styles as much up front. It’s happened more times than I’d like to admit where I get stuck deciding on color shades for an hour without getting much else done.

Building the nav

The first thing to do is “import” the Bootstrap css and js files. This bootstrap nav dropdown example is just a single html file, so I’ll usee the bootstrap cdn links instead of downloading the files. There is a performance penalty for using the cdn, but the convenience factor makes it worth it for quick prototypes.

...
<link
  href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css"
  rel="stylesheet"
  integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU"
  crossorigin="anonymous"
/>
<script
  src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"
  integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ"
  crossorigin="anonymous"
></script>
...

After that, I’ll add a header tag and start building the navbar. I didn’t need to use the header tag, but I prefer using semantic html since it makes the code easier to understand for me in the future. It also makes things easier for anyone viewing the site using a screen reader.

...
<header>
  <div class="container d-flex align-items-center">...</div>
</header>
...

Inside the header element is a child div that contains all of the rest of the elements that make up the header. In this element I add the bootstrap container utility class which creates some space between the left and right sides of the page. I could’ve moves all of the classes in the child div to the parent header element but I want the header to span the entire width of the page without space on either side.

Next up is the header text. This is usually large bold text that says the app or page name. I used Bootstrap’s fs-4 utility class which cleverly increases the font-size based on the screen size via calc(1.275rem + .3vw)!important. The header text should also take the user “home”, so it needs to be wrapped in a anchor tag. To prevent the text from having an underline and being blue, I used the Bootstrap text-decoration-none and text-dark utility classes.

...
<a href="#home" class="text-decoration-none text-dark">
  <span class="fs-4">bored.io</span>
</a>
...

The nav links and dropdowns themselves will sit inside of a nav element containing a child ul element that is styled by the Bootstrap nav utility class. This class initializes a flexbox container for the links to sit inside of, and adjusts the spacing to be more visually pleasing. The flexbox container changes the ul orientation from vertical to horizontal.

...
<nav>
  <ul class="nav ms-3">
    ...
  </ul>
</nav>

The last piece to this bootstrap nav is the dropdowns. Most of the code below is copied straight from the Bootstrap dropdown example docs. The basic idea is that each dropdown is a li element with a child wrapper dropdown div element that contains a button to toggle the menu opened and closed. The border-primary class on the li element is meant to denote that the “Dashboard” page is active.

...
<li class="nav-item border-bottom border-2 border-primary">
  <div class="dropdown">
    <button
      class="btn dropdown-toggle"
      type="button"
      data-bs-toggle="dropdown"
      aria-expanded="false"
    >
      Dashboard
    </button>
    <ul class="dropdown-menu">
      <li><button class="dropdown-item" type="button">Feed</button></li>
      <li><button class="dropdown-item" type="button">Analytics</button></li>
      <li><button class="dropdown-item" type="button">Revenue</button></li>
    </ul>
  </div>
</li>
...

Bootstrap dropdown menus only open when the button is clicked. According to the docs this is intentional. I don’t mind it either. I think the “hover to open” pattern can be annoying and hard to navigate. The click to open allows the user to state their intentions and not be surprised.

Conclusion

This Bootstrap nav dropdown example was pretty easy to build. It is, of course, a mostly contrived example. But it’s one that’s easy to expand on and build into more a more complex navigation. Again, this is why I like bootstrap for rapid prototypes. Some of the tough things are built for me and it saves me a lot of time, even if I have to give up some control of the styling. At least initially, anyways.