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-togglerreceivesdisplay: noneand.navbar-collapseshows as a flex container - Below the breakpoint: The menu hides via
display: noneon.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>
Navbar with Brand and Search Form
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>
Dropdown Inside Collapsed Menu
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-iconin your stylesheet to change the SVG fill color - Animation speed: Modify the
$transition-collapsevariable 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 matchingdata-bs-targetandidattributes - 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.scsswhile toggle logic lives injs/src/collapse.js - Dependencies: Include
bootstrap.bundle.min.jsto ensure the Collapse plugin and Popper utilities are available - Accessibility: Always include
aria-controls,aria-expanded, andaria-labelattributes 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →