How to Create a Bootstrap Hamburger Menu: Responsive Navbar Guide

Wrap your navigation links in a .navbar-collapse container and pair it with a .navbar-toggler button that targets the collapse element via data-bs-toggle="collapse" to create a responsive hamburger menu.

Bootstrap’s navigation system transforms standard menus into mobile-friendly hamburger interfaces through the Navbar component. According to the twbs/bootstrap source code, this behavior relies on coordinated SCSS breakpoints in scss/_navbar.scss and JavaScript collapse logic in js/src/collapse.js. By combining specific CSS classes with data attributes, you can control exactly when your menu collapses into the iconic three-line toggle button.

Understanding the Bootstrap Navbar Component Structure

The hamburger functionality requires two distinct markup sections working together. The toggler button contains the visual hamburger icon and serves as the click target, while the collapsible wrapper holds the actual navigation content that hides and shows.

This architecture separates concerns: CSS handles the responsive visibility rules based on viewport width, while the Bootstrap JavaScript manages the state toggling and accessibility attributes when users interact with the button.

Required HTML Markup for a Bootstrap Hamburger Menu

Every responsive navbar follows this specific pattern to ensure compatibility with Bootstrap’s collapse plugin.

The Toggler Button

The button element triggers the collapse behavior and displays the hamburger icon:

<button
  class="navbar-toggler"
  type="button"
  data-bs-toggle="collapse"
  data-bs-target="#mainNavbar"
  aria-controls="mainNavbar"
  aria-expanded="false"
  aria-label="Toggle navigation">
  <span class="navbar-toggler-icon"></span>
</button>

The data-bs-target attribute must match the id of your collapsible menu container. The .navbar-toggler-icon class renders the three horizontal lines using a background SVG defined in the Bootstrap CSS.

The Collapsible Container

Wrap your navigation items in a div with the collapse classes:

<div class="collapse navbar-collapse" id="mainNavbar">
  <ul class="navbar-nav me-auto mb-2 mb-lg-0">
    <li class="nav-item"><a class="nav-link" href="#">Home</a></li>
    <li class="nav-item"><a class="nav-link" href="#">Features</a></li>
    <li class="nav-item"><a class="nav-link" href="#">Pricing</a></li>
  </ul>
</div>

The id attribute here must correspond to the data-bs-target value on your toggler button. The .collapse class sets display: none by default, while .navbar-collapse applies flexbox utilities specific to navigation layouts.

How the Responsive Behavior Works

In scss/_navbar.scss, Bootstrap defines breakpoint-specific rules that determine when the toggler appears and when the full menu displays. The navbar-expand-* class on your <nav> element sets the threshold:

  • Above the breakpoint: The .navbar-toggler receives display: none and .navbar-collapse shows as a flex container
  • Below the breakpoint: The menu hides via display: none on .collapse, and the toggler button becomes visible

When a user clicks the toggler, the JavaScript in js/src/collapse.js instantiates the Collapse class, which toggles the .show class on the target container. This class overrides the display property, causing the menu to animate open with a sliding effect.

Controlling the Breakpoint with navbar-expand-* Classes

The breakpoint at which your menu transforms into a hamburger is determined by the expand class appended to your navbar:

  • .navbar-expand-sm: Hamburger appears below 576px
  • .navbar-expand-md: Hamburger appears below 768px
  • .navbar-expand-lg: Hamburger appears below 992px (most common default)
  • .navbar-expand-xl: Hamburger appears below 1200px
  • .navbar-expand-xxl: Hamburger appears below 1400px

Choose the class that matches your design requirements. If you omit the navbar-expand-* class entirely, the menu remains collapsed (hamburger-only) at all viewport sizes.

Practical Code Examples

Minimal Hamburger Menu

Use this stripped-down version when you need only navigation links without branding or right-aligned content:

<nav class="navbar navbar-expand-md navbar-dark bg-primary">
  <button class="navbar-toggler" type="button"
          data-bs-toggle="collapse" data-bs-target="#navMenu"
          aria-controls="navMenu" aria-expanded="false"
          aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navMenu">
    <ul class="navbar-nav me-auto">
      <li class="nav-item"><a class="nav-link" href="#">Link 1</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Link 2</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Link 3</a></li>
    </ul>
  </div>
</nav>

This example demonstrates the classic layout with a brand logo and right-aligned search functionality:

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">MySite</a>

  <button class="navbar-toggler" type="button"
          data-bs-toggle="collapse" data-bs-target="#navbarContent"
          aria-controls="navbarContent" aria-expanded="false"
          aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarContent">
    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
      <li class="nav-item"><a class="nav-link active" href="#">Home</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Docs</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Contact</a></li>
    </ul>
    <form class="d-flex">
      <input class="form-control me-2" type="search" placeholder="Search">
      <button class="btn btn-outline-success" type="submit">Search</button>
    </form>
  </div>
</nav>

When you need nested navigation that works within the hamburger menu:

<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
  <a class="navbar-brand" href="#">Demo</a>

  <button class="navbar-toggler" type="button"
          data-bs-toggle="collapse" data-bs-target="#demoNav"
          aria-controls="demoNav" aria-expanded="false"
          aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="demoNav">
    <ul class="navbar-nav me-auto">
      <li class="nav-item"><a class="nav-link" href="#">Home</a></li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" role="button"
           data-bs-toggle="dropdown" aria-expanded="false">
          Services
        </a>
        <ul class="dropdown-menu">
          <li><a class="dropdown-item" href="#">Design</a></li>
          <li><a class="dropdown-item" href="#">Development</a></li>
          <li><a class="dropdown-item" href="#">Consulting</a></li>
        </ul>
      </li>
    </ul>
  </div>
</nav>

Including the Required CSS and JavaScript

For the hamburger menu to function, you must load both the compiled CSS and the JavaScript bundle. If using the Bootstrap npm package, import both files in your entry point:

import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';

The bootstrap.bundle.min.js file includes Popper, which is required for dropdown positioning within collapsed menus. Alternatively, include the CDN links in your HTML:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

Customizing Your Hamburger Menu

You can override default Bootstrap behaviors through custom CSS or by modifying the source variables in scss/_navbar.scss:

  • Always-visible hamburger: Remove the navbar-expand-* class entirely to keep the menu collapsed at all breakpoints
  • Icon color: Target .navbar-toggler-icon in your stylesheet to change the SVG fill color
  • Animation speed: Modify the $transition-collapse variable in the Bootstrap SCSS variables file to adjust the sliding animation duration

Summary

  • Markup structure: Combine .navbar-toggler (the button) with .collapse.navbar-collapse (the menu container) linked by matching data-bs-target and id attributes
  • Breakpoint control: Use .navbar-expand-lg, .navbar-expand-md, or other size variants to set when the hamburger appears
  • Source files: Responsive styles reside in scss/_navbar.scss while toggle logic lives in js/src/collapse.js
  • Dependencies: Include bootstrap.bundle.min.js to ensure the Collapse plugin and Popper utilities are available
  • Accessibility: Always include aria-controls, aria-expanded, and aria-label attributes on your toggler button for screen reader support

Frequently Asked Questions

What is the default breakpoint for Bootstrap hamburger menus?

Bootstrap does not enforce a default breakpoint; you must explicitly specify one using the .navbar-expand-* class. If you omit this class, the menu remains in hamburger mode at all viewport sizes. The most commonly used class is .navbar-expand-lg, which triggers the hamburger below 992px.

Do I need to write custom JavaScript to toggle the menu?

No. The collapse functionality is handled automatically by the Bootstrap JavaScript bundle. When you include bootstrap.bundle.min.js, the library detects elements with data-bs-toggle="collapse" and instantiates the Collapse class from js/src/collapse.js, managing the .show class and ARIA attributes without additional code.

How do I change the hamburger icon color?

The .navbar-toggler-icon uses an embedded SVG background image. To change its color, override the CSS background-image property or use the navbar-dark class on your navbar for a white icon, and navbar-light for a dark icon. For custom colors, modify the $navbar-light-toggler-icon-bg or $navbar-dark-toggler-icon-bg SCSS variables before compiling.

Can I make the hamburger menu always visible regardless of screen size?

Yes. Remove the navbar-expand-* class from your <nav> element entirely. Without this class, Bootstrap assumes the menu should always remain collapsed, keeping the hamburger button visible and the navigation links hidden until clicked. You can then control visibility purely through the collapse toggle without media query interference.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →