Bootstrap Navbar: 16 Examples, From Basic to Offcanvas

The Bootstrap navbar is the header component: brand, nav links, an optional search form and dropdowns, all folded behind a toggler below the breakpoint set by a navbar-expand-{sm|md|lg|xl|xxl} class.

Below are 16 Bootstrap navbar examples you can copy, followed by a guide to breakpoints, color modes, dropdowns, offcanvas menus and common fixes.

By Bogdan Sandu ยท Updated October 29, 2026

Every example runs on Bootstrap 5.3.8 from the jsDelivr CDN. Add these tags to your page, then paste an example's HTML, CSS and JS.

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.2/font/bootstrap-icons.min.css" rel="stylesheet" integrity="sha384-nWN3KqaaVcbEsCjLSV+2jMjh62Iny/+mN3srM8TZeM8N6aj7eDl5wwYggjAJ4/sJ" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>

Everyday navbars

Four headers you will build again and again: a product bar with a call to action, a centered logo, a docs bar with search and a dark scheme set with data-bs-theme.

SaaS navbar with a call to action

  • navbar-expand-md
  • me-auto
  • --bs-btn-*

On a phone the links collapse behind the toggler. Tap it to open the menu.

A classic product header: brand mark, four links pushed left with me-auto and a log in link plus trial button on the right. The button is recolored through its --bs-btn-* variables, and the bar padding and active color come from --bs-navbar-padding-y and --bs-navbar-active-color.

View code
<nav class="navbar navbar-expand-md bg-body border-bottom bnv-saas w-100" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand d-flex align-items-center gap-2 fw-semibold" href="#">
      <svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><rect width="30" height="30" rx="8" fill="#4338ca"/><path d="M8 19l5-8 3.5 5.5 2.5-3.5 3 6" fill="none" stroke="#fff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
      Ledgerly
    </a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-saas-menu" aria-controls="bnv-saas-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="bnv-saas-menu">
      <ul class="navbar-nav me-auto mb-2 mb-md-0">
        <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Product</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Pricing</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Customers</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Changelog</a></li>
      </ul>
      <div class="d-flex flex-column flex-md-row align-items-md-center gap-2 pb-3 pb-md-0">
        <a class="btn btn-link text-body text-decoration-none fw-medium" href="#">Log in</a>
        <a class="btn bnv-saas-cta" href="#">Start free trial</a>
      </div>
    </div>
  </div>
</nav>

Dark navbar with data-bs-theme

  • data-bs-theme="dark"
  • bg-dark
  • navbar-text

On a phone the links collapse behind the toggler. Tap it to open the menu.

The 5.3 way to build a dark bar: data-bs-theme="dark" on the .navbar switches the link, brand and toggler colors, and bg-dark with border-bottom border-body supplies the background, exactly as in the docs. navbar-text carries a small availability status next to the button.

View code
<nav class="navbar navbar-expand-md bg-dark border-bottom border-body bnv-dark w-100" data-bs-theme="dark" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand fw-bold" href="#">northpaw<span class="bnv-dark-dot">.</span>studio</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-dark-menu" aria-controls="bnv-dark-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="bnv-dark-menu">
      <ul class="navbar-nav me-auto mb-2 mb-md-0">
        <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Work</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Services</a></li>
        <li class="nav-item"><a class="nav-link" href="#">About</a></li>
      </ul>
      <span class="navbar-text d-inline-flex align-items-center gap-2 me-md-3 small">
        <span class="bnv-dark-status" aria-hidden="true"></span>Booking Q1 2027
      </span>
      <a class="btn btn-light fw-semibold d-block d-md-inline-block my-2 my-md-0 bnv-dark-btn" href="#">Start a project</a>
    </div>
  </div>
</nav>

Themed with CSS variables

Bootstrap 5.3 drives the navbar with --bs-navbar-* variables, so a few lines of CSS change colors, spacing and the toggler without touching Sass.

Navbar themed with --bs-navbar-* variables

  • --bs-navbar-color
  • --bs-navbar-toggler-icon-bg
  • --bs-navbar-nav-link-padding-x

Every color and spacing value here is a --bs-navbar-* variable set on one class: link, hover, active and brand colors, padding, link spacing and the toggler border, radius and icon. The only extra rule is the underline on the active link.

View code
<nav class="navbar navbar-expand-md bnv-vars w-100" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand" href="#">Ember &amp; Oak</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-vars-menu" aria-controls="bnv-vars-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="bnv-vars-menu">
      <ul class="navbar-nav ms-auto mb-2 mb-md-0">
        <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Coffee</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Subscriptions</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Brew guides</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Wholesale</a></li>
        <li class="nav-item"><a class="nav-link disabled" aria-disabled="true">Cafe (opens May)</a></li>
      </ul>
    </div>
  </div>
</nav>

Floating pill navbar

  • rounded-pill
  • shadow-sm
  • --bs-navbar-active-color

The navbar floats as a card: utilities add the border, shadow and pill radius from md up, and the active link becomes a filled pill. The container is just a narrower .navbar padding, so the same markup still collapses on phones.

View code
<nav class="navbar navbar-expand-md bg-body border shadow-sm w-100 bnv-pill" aria-label="Main">
  <div class="container-fluid">
    <a class="navbar-brand d-flex align-items-center gap-2 fw-semibold" href="#">
      <svg width="26" height="26" viewBox="0 0 26 26" aria-hidden="true"><circle cx="13" cy="13" r="12" fill="#0e7490"/><path d="M5 15c3-3 5-3 8 0s5 3 8 0" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round"/></svg>
      Tidepool
    </a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-pill-menu" aria-controls="bnv-pill-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="bnv-pill-menu">
      <ul class="navbar-nav mx-auto gap-md-1 my-2 my-md-0">
        <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Overview</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Dashboards</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Alerts</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Docs</a></li>
      </ul>
      <a class="btn btn-outline-dark rounded-pill px-3 mb-2 mb-md-0" href="#">Sign in</a>
    </div>
  </div>
</nav>

Transparent navbar over a hero photo

  • no bg-* class
  • data-bs-theme="dark"
  • Collapse.getOrCreateInstance

With no bg-* class the navbar is transparent, and data-bs-theme="dark" turns its text light over the darkened photo. On phones the open menu gets its own solid panel, and a short script closes the collapse when an in-page link is clicked.

View code
<div class="position-relative overflow-hidden bnv-hero w-100">
  <img class="bnv-hero-img" src="fjord.webp" alt="Deep blue fjord between grey cliffs, seen from a rocky plateau with hikers" width="800" height="600">
  <nav class="navbar navbar-expand-md position-absolute top-0 start-0 w-100 bnv-hero-nav" data-bs-theme="dark" aria-label="Main">
    <div class="container-fluid px-md-4">
      <a class="navbar-brand fw-bold" href="#">Nordleia</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-hero-menu" aria-controls="bnv-hero-menu" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="bnv-hero-menu">
        <ul class="navbar-nav ms-auto">
          <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Trips</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Ships</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Seasons</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Contact</a></li>
        </ul>
      </div>
    </div>
  </nav>
  <div class="position-absolute bottom-0 start-0 p-4 p-md-5 text-white bnv-hero-copy">
    <h2 class="fw-bold mb-3">Seven days on the western fjords</h2>
    <a class="btn btn-light fw-semibold px-4 py-2" href="#">See departures</a>
  </div>
</div>

Always-collapsed navbar with an animated toggler

  • no navbar-expand class
  • aria-expanded styling
  • custom toggler

Click the menu button.

Leaving out every navbar-expand class keeps the menu collapsed at all widths, a common portfolio pattern. The toggler draws its own three bars and morphs them into an X by reading the aria-expanded value that the Collapse plugin already updates.

View code
<nav class="navbar bnv-burger w-100" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand" href="#">Studio Halden</a>
    <button class="navbar-toggler bnv-burger-btn" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-burger-menu" aria-controls="bnv-burger-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="bnv-burger-bars" aria-hidden="true"><span></span><span></span><span></span></span>
      <span class="ms-2 d-none d-sm-inline">Menu</span>
    </button>
    <div class="collapse navbar-collapse" id="bnv-burger-menu">
      <div class="row g-4 pt-4 pb-3">
        <div class="col-md-7">
          <ul class="navbar-nav bnv-burger-links">
            <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Selected work</a></li>
            <li class="nav-item"><a class="nav-link" href="#">Studio</a></li>
            <li class="nav-item"><a class="nav-link" href="#">Writing</a></li>
            <li class="nav-item"><a class="nav-link" href="#">Contact</a></li>
          </ul>
        </div>
        <div class="col-md-5 bnv-burger-side">
          <p class="mb-1 fw-semibold">Oslo and remote</p>
          <p class="mb-3">Brand identities and websites for cultural institutions.</p>
          <a class="link-dark fw-semibold" href="#">hello@studiohalden.example</a>
        </div>
      </div>
    </div>
  </div>
</nav>

Dropdowns, mega menus and offcanvas

Navbar dropdowns are positioned by CSS instead of Popper, and the same markup turns into a drawer with the offcanvas component.

Mega menu built with the grid

  • position-static
  • dropdown-menu w-100
  • row / col

Click a menu. On a phone, open the toggler first.

The trick is position-static on the .nav-item.dropdown: the menu then anchors to the .navbar itself, and w-100 stretches it across the bar. Inside it is plain grid markup with icon links and a promo card, which stacks inside the collapse on phones.

View code
<nav class="navbar navbar-expand-md bg-body border-bottom bnv-mega w-100" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand fw-bold d-flex align-items-center gap-2" href="#"><i class="bi bi-ui-checks-grid bnv-mega-logo" aria-hidden="true"></i>Formwell</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-mega-menu" aria-controls="bnv-mega-menu" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="bnv-mega-menu">
      <ul class="navbar-nav me-auto">
        <li class="nav-item dropdown position-static">
          <a class="nav-link dropdown-toggle bnv-mega-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">Platform</a>
          <div class="dropdown-menu w-100 mt-0 border-0 border-top rounded-0 bnv-mega-panel">
            <div class="row g-4">
              <div class="col-md-4">
                <p class="bnv-mega-heading">Build</p>
                <a class="bnv-mega-link" href="#"><i class="bi bi-ui-radios" aria-hidden="true"></i><span><strong>Forms</strong>Drag and drop fields, logic and steps</span></a>
                <a class="bnv-mega-link" href="#"><i class="bi bi-lightning-charge" aria-hidden="true"></i><span><strong>Automations</strong>Route answers to the right team</span></a>
                <a class="bnv-mega-link" href="#"><i class="bi bi-plug" aria-hidden="true"></i><span><strong>Integrations</strong>Sheets, CRMs and webhooks</span></a>
              </div>
              <div class="col-md-4">
                <p class="bnv-mega-heading">Learn</p>
                <a class="bnv-mega-link" href="#"><i class="bi bi-book" aria-hidden="true"></i><span><strong>Guides</strong>Step by step setup articles</span></a>
                <a class="bnv-mega-link" href="#"><i class="bi bi-grid-1x2" aria-hidden="true"></i><span><strong>Templates</strong>More than 300 ready forms</span></a>
                <a class="bnv-mega-link" href="#"><i class="bi bi-camera-video" aria-hidden="true"></i><span><strong>Webinars</strong>Live sessions every Thursday</span></a>
              </div>
              <div class="col-md-4">
                <div class="bnv-mega-card h-100">
                  <p class="fw-semibold mb-1">New: payment fields</p>
                  <p class="small mb-3">Collect deposits and order totals right inside a form.</p>
                  <a class="btn btn-sm bnv-mega-btn" href="#">Read the release notes</a>
                </div>
              </div>
            </div>
          </div>
        </li>
        <li class="nav-item"><a class="nav-link" href="#">Templates</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Pricing</a></li>
      </ul>
      <a class="btn bnv-mega-btn mb-3 mb-md-0" href="#">Create a form</a>
    </div>
  </div>
</nav>

Offcanvas mobile menu

  • offcanvas offcanvas-end
  • navbar-expand-md
  • data-bs-dismiss

Click a menu. On a phone, open the toggler first.

With navbar-expand-md the offcanvas markup renders as a normal inline bar from md up, and below that the toggler opens it as a drawer with a backdrop, focus handling and Esc to close. The panel width is set with --bs-offcanvas-width so it leaves a strip of page visible on small phones.

View code
<nav class="navbar navbar-expand-md bg-body border-bottom bnv-oc w-100" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand fw-bold d-flex align-items-center gap-2" href="#"><span class="bnv-oc-mark" aria-hidden="true">A</span>Atlas Transit</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#bnv-oc-panel" aria-controls="bnv-oc-panel" aria-label="Open menu">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="offcanvas offcanvas-end bnv-oc-panel" tabindex="-1" id="bnv-oc-panel" aria-labelledby="bnv-oc-title">
      <div class="offcanvas-header border-bottom">
        <h2 class="offcanvas-title fs-5" id="bnv-oc-title">Atlas Transit</h2>
        <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
      </div>
      <div class="offcanvas-body align-items-md-center">
        <ul class="navbar-nav flex-grow-1 justify-content-md-end me-md-3">
          <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Routes</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Fares</a></li>
          <li class="nav-item"><a class="nav-link d-flex align-items-center gap-2" href="#">Alerts <span class="badge rounded-pill text-bg-warning">2<span class="visually-hidden"> active service alerts</span></span></a></li>
          <li class="nav-item"><a class="nav-link" href="#">Accessibility</a></li>
        </ul>
        <a class="btn bnv-oc-btn mt-3 mt-md-0" href="#">Plan a trip</a>
      </div>
    </div>
  </div>
</nav>

App navbar with avatar dropdown

  • data-bs-theme="dark"
  • badge
  • dropdown-menu-end

Click a menu. On a phone, open the toggler first.

A dashboard bar on a custom dark teal: data-bs-theme="dark" on the navbar also gives its dropdown dark colors with no dropdown-menu-dark class. The bell is an icon button with an aria-label and a positioned badge, and the avatar is a button-styled toggle with initials.

View code
<nav class="navbar navbar-expand-md bnv-app w-100" data-bs-theme="dark" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand fw-bold d-flex align-items-center gap-2" href="#"><i class="bi bi-kanban" aria-hidden="true"></i>Trellwork</a>
    <div class="d-flex align-items-center gap-1 order-md-last ms-auto">
      <button type="button" class="btn bnv-app-icon position-relative" aria-label="Notifications, 3 unread">
        <i class="bi bi-bell" aria-hidden="true"></i>
        <span class="position-absolute translate-middle badge rounded-pill bnv-app-badge" aria-hidden="true">3</span>
      </button>
      <div class="dropdown">
        <button type="button" class="btn bnv-app-avatar dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Account menu for Priya Nair">PN</button>
        <ul class="dropdown-menu dropdown-menu-end">
          <li><span class="dropdown-item-text"><strong class="d-block">Priya Nair</strong><span class="small text-body-secondary">priya@trellwork.example</span></span></li>
          <li><hr class="dropdown-divider"></li>
          <li><a class="dropdown-item" href="#"><i class="bi bi-person me-2" aria-hidden="true"></i>Profile</a></li>
          <li><a class="dropdown-item" href="#"><i class="bi bi-gear me-2" aria-hidden="true"></i>Settings</a></li>
          <li><hr class="dropdown-divider"></li>
          <li><a class="dropdown-item" href="#"><i class="bi bi-box-arrow-right me-2" aria-hidden="true"></i>Sign out</a></li>
        </ul>
      </div>
      <button class="navbar-toggler ms-1" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-app-menu" aria-controls="bnv-app-menu" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
    </div>
    <div class="collapse navbar-collapse" id="bnv-app-menu">
      <ul class="navbar-nav me-auto mb-2 mb-md-0">
        <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Projects</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Reports</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Team</a></li>
      </ul>
    </div>
  </div>
</nav>

Layout patterns

Two-tier headers, a shop bar with a cart badge, a sticky navbar with Scrollspy and a bottom tab bar for app screens.

Two-tier header with a utility bar

  • navbar-expand
  • two <nav> landmarks
  • aria-label

Two navbars stacked in one header. The slim utility bar uses navbar-expand so it never collapses, while the main bar collapses at md. Each nav gets its own aria-label so screen reader users can tell the two landmarks apart.

View code
<header class="bnv-tier w-100">
  <nav class="navbar navbar-expand bnv-tier-top" data-bs-theme="dark" aria-label="Account and help">
    <div class="container-fluid px-md-4">
      <span class="navbar-text d-none d-sm-inline">Harbor City, 12ยฐC and clear</span>
      <ul class="navbar-nav ms-auto align-items-center gap-2">
        <li class="nav-item"><a class="nav-link" href="#">Newsletters</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Sign in</a></li>
        <li class="nav-item"><a class="btn btn-sm bnv-tier-sub" href="#">Subscribe</a></li>
      </ul>
    </div>
  </nav>
  <nav class="navbar navbar-expand-md bg-body border-bottom bnv-tier-main" aria-label="Sections">
    <div class="container-fluid px-md-4">
      <a class="navbar-brand bnv-tier-brand" href="#">The Harbor Ledger</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-tier-menu" aria-controls="bnv-tier-menu" aria-expanded="false" aria-label="Toggle sections">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="bnv-tier-menu">
        <ul class="navbar-nav ms-auto mb-2 mb-md-0">
          <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">City</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Business</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Climate</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Culture</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Opinion</a></li>
        </ul>
      </div>
    </div>
  </nav>
</header>

E-commerce navbar with cart badge

  • Bootstrap Icons
  • badge translate-middle
  • order-md-*

The icon group sits outside the collapse, so search, account and cart stay visible on phones while the category links fold away. Order utilities move the icons to the far right from md up, and the cart count is a positioned badge with visually hidden text.

View code
<nav class="navbar navbar-expand-md bg-body border-bottom bnv-shop w-100" aria-label="Main">
  <div class="container-fluid px-md-4">
    <a class="navbar-brand bnv-shop-brand" href="#">Fernwood<span>Supply</span></a>
    <div class="d-flex align-items-center ms-auto order-md-2">
      <a class="btn bnv-shop-icon d-none d-sm-inline-flex" href="#" aria-label="Search"><i class="bi bi-search" aria-hidden="true"></i></a>
      <a class="btn bnv-shop-icon" href="#" aria-label="Account"><i class="bi bi-person" aria-hidden="true"></i></a>
      <a class="btn bnv-shop-icon position-relative" href="#">
        <i class="bi bi-bag" aria-hidden="true"></i>
        <span class="visually-hidden">Cart</span>
        <span class="position-absolute translate-middle badge rounded-pill bnv-shop-badge">2<span class="visually-hidden"> items</span></span>
      </a>
      <button class="navbar-toggler ms-1" type="button" data-bs-toggle="collapse" data-bs-target="#bnv-shop-menu" aria-controls="bnv-shop-menu" aria-expanded="false" aria-label="Toggle categories">
        <span class="navbar-toggler-icon"></span>
      </button>
    </div>
    <div class="collapse navbar-collapse order-md-1" id="bnv-shop-menu">
      <ul class="navbar-nav mx-md-auto mb-2 mb-md-0">
        <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">New in</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Camp</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Kitchen</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Apparel</a></li>
        <li class="nav-item"><a class="nav-link bnv-shop-sale" href="#">Sale</a></li>
      </ul>
    </div>
  </div>
</nav>

Sticky navbar with Scrollspy

  • sticky-top
  • data-bs-spy="scroll"
  • data-bs-root-margin

Scroll inside the box and watch the navbar stay put while the active link follows the section.

The navbar uses sticky-top inside a scrolling container, which stands in for the page here. Scrollspy is set on that container with data-bs-spy, data-bs-target and a rootMargin, and it moves .active along the links as each section crosses the upper part of the box.

View code
<div class="bnv-spy w-100" id="bnv-spy-scroll" data-bs-spy="scroll" data-bs-target="#bnv-spy-nav" data-bs-root-margin="0px 0px -60%" data-bs-smooth-scroll="true" tabindex="0">
  <nav class="navbar navbar-expand sticky-top bg-body border-bottom bnv-spy-bar" id="bnv-spy-nav" aria-label="Guide sections">
    <div class="container-fluid">
      <a class="navbar-brand d-none d-sm-block" href="#bnv-spy-overview">Ridge Loop</a>
      <ul class="navbar-nav ms-sm-auto">
        <li class="nav-item"><a class="nav-link" href="#bnv-spy-overview">Overview</a></li>
        <li class="nav-item"><a class="nav-link" href="#bnv-spy-route">Route</a></li>
        <li class="nav-item"><a class="nav-link" href="#bnv-spy-gear">Gear</a></li>
        <li class="nav-item"><a class="nav-link" href="#bnv-spy-permits">Permits</a></li>
      </ul>
    </div>
  </nav>
  <div class="bnv-spy-body">
    <div id="bnv-spy-overview"><h3>Overview</h3><p>The Ridge Loop is a 14 km day hike with 820 m of climbing. Most hikers finish in six to seven hours, with the best light on the eastern ridge before ten in the morning.</p><p>Water is available at the trailhead and at the hut halfway round. Phone coverage drops out on the far side of the ridge.</p></div>
    <div id="bnv-spy-route"><h3>Route</h3><p>Start at the lower car park and follow the red markers through birch forest. After 3 km the trail leaves the trees and climbs steeply to the first cairn.</p><p>The ridge itself is broad and easy to follow in clear weather. In fog, keep the drop on your left and use the marker poles.</p></div>
    <div id="bnv-spy-gear"><h3>Gear</h3><p>Boots with ankle support, a wind shell, two litres of water and a paper map. Trekking poles help a lot on the descent.</p><p>Snow can linger on the north side until late June, so check the conditions page before you leave.</p></div>
    <div id="bnv-spy-permits"><h3>Permits</h3><p>No permit is needed for day hikes. Overnight stays at the hut must be booked in advance, and wild camping is allowed more than 150 m from the trail.</p><p>Dogs must be on a lead between April and August.</p></div>
  </div>
</div>

Bottom tab bar for mobile

  • navbar-nav flex-row
  • aria-current
  • Bootstrap Icons

Tap a tab.

An app-style tab bar made from a .navbar whose .navbar-nav is switched to a row with flex-row and spread out with justify-content-around. On a real page you would add fixed-bottom and d-md-none, and the small script moves .active and aria-current to the tapped tab.

View code
<div class="bnv-tabs-app border bg-body">
  <div class="bnv-tabs-screen">
    <p class="bnv-tabs-date mb-1">Tuesday</p>
    <h3 class="bnv-tabs-title">Today</h3>
    <div class="bnv-tabs-card"><i class="bi bi-bicycle" aria-hidden="true"></i><span><strong>Easy spin</strong>45 min, zone 2</span></div>
    <div class="bnv-tabs-card"><i class="bi bi-heart-pulse" aria-hidden="true"></i><span><strong>Mobility</strong>15 min, hips and back</span></div>
  </div>
  <nav class="navbar border-top bg-body bnv-tabs" aria-label="App sections">
    <ul class="navbar-nav flex-row w-100 justify-content-around">
      <li class="nav-item"><a class="nav-link active" aria-current="page" href="#"><i class="bi bi-house-door" aria-hidden="true"></i>Home</a></li>
      <li class="nav-item"><a class="nav-link" href="#"><i class="bi bi-compass" aria-hidden="true"></i>Explore</a></li>
      <li class="nav-item"><a class="nav-link" href="#"><i class="bi bi-bar-chart" aria-hidden="true"></i>Progress</a></li>
      <li class="nav-item"><a class="nav-link" href="#"><i class="bi bi-person" aria-hidden="true"></i>Profile</a></li>
    </ul>
  </nav>
</div>

What Is a Bootstrap Navbar?

It’s a piece of the Bootstrap framework that lays out its children with flexbox. You pick the breakpoint where it collapses, and the Collapse plugin does the hiding and showing.

The official docs name these parts:

  • .navbar-brand, the site or project name (an anchor works best)
  • .navbar-nav, the link group, built on the .nav component and able to hold dropdowns
  • .navbar-toggler, the button that opens and closes collapsed content
  • flex and spacing utilities for forms and action buttons
  • .navbar-text for vertically centered strings of text
  • .collapse.navbar-collapse, which groups and hides content below a breakpoint
  • .navbar-nav-scroll, which adds a max-height and vertical scrolling inside collapsed menus

Navbars and their contents are fluid by default. Immediate children of .navbar use flex layout with justify-content: space-between, and the link group grows to fill whatever horizontal space is left.

Since it usually serves as the navigation of a site, assistive technology should read it as a landmark region. Use a nav element, or role=”navigation” on a generic div.

The link for the current page gets aria-current=”page” (Bootstrap documentation).

How to Build a Basic Responsive Bootstrap Navbar

The Bootstrap CSS file and bootstrap.bundle.min.js come first. After that it’s a chain of markup: a wrapper, a container, the brand, the toggler, the collapse block and the link list.

  1. Load bootstrap.min.css from the jsDelivr CDN in the head of the page.
  2. Load bootstrap.bundle.min.js from jsDelivr after the page content.
  3. Add a nav element with the classes navbar, navbar-expand-lg and bg-body-tertiary.
  4. Put a container-fluid div inside it. Swap in container or a responsive container such as container-md if you want to limit the width.
  5. Add an anchor with navbar-brand, then a button with navbar-toggler, data-bs-toggle=”collapse” and a data-bs-target that points to the collapse block id. A span with navbar-toggler-icon goes inside the button.
  6. Add a div with collapse, navbar-collapse and that id. Inside it goes a ul.navbar-nav with li.nav-item and a.nav-link children, and the link for the current page gets active and aria-current=”page”.

The result is plain HTML markup, and the default look needs no custom CSS.

Don’t skip the container. Bootstrap 5 treats it as required, and the v5.0.0 migration notes list that as a breaking change from Bootstrap 4.

In Bootstrap 5 the plugins were rewritten in vanilla JavaScript, so no jQuery gets loaded. Version 4.6 works differently. Its bundle includes Popper but not jQuery, so jQuery has to load first (Bootstrap 4.6 documentation).

The bundle matters most for dropdowns. They need Popper, and bootstrap.bundle.min.js already contains it, while the separate bootstrap.min.js file needs Popper loaded before it.

Pin the CDN URL to a specific release. The docs footer lists v5.3.8 as current as of October 2026, and the introduction page carries the full tags with integrity hashes to copy.

How the Navbar-Expand Classes Set the Collapse Point

The navbar-expand-{breakpoint} class sets the viewport width where the navbar stops collapsing and lays its links out in one row. Below that width the toggler shows and the .navbar-collapse block stays hidden.

Each class maps to a min-width media query from Bootstrap’s grid breakpoints. The layout is mobile-first, so the rule applies from that width upward (Bootstrap documentation):

  • navbar-expand-sm: 576px and up
  • navbar-expand-md: 768px and up
  • navbar-expand-lg: 992px and up
  • navbar-expand-xl: 1200px and up
  • navbar-expand-xxl: 1400px and up

The xxl tier arrived with v5.0.0, so navbar-expand-xxl does not exist in Bootstrap 4.

If you want a navbar that never collapses, add .navbar-expand with no suffix. For one that always collapses, leave out every .navbar-expand class.

The toggler only works when its attributes line up with the collapse block. data-bs-toggle=”collapse” hands the button to the Collapse plugin, and data-bs-target=”#id” points to the id of the .navbar-collapse block. aria-controls repeats that id for assistive technology. aria-expanded=”false” sets the starting closed state, and aria-label=”Toggle navigation” gives the icon-only button a name.

Those ARIA attributes matter because the hamburger icon has no visible text, so a screen reader has nothing else to announce.

The plugin matches the data-bs-target value to the id. A typo in either one leaves the button inert, and nothing in the console will tell you why.

Placed after the brand, the toggler sits at the far right. Reverse the markup order and it moves to the left.

The collapse animation follows the prefers-reduced-motion media query, per the Bootstrap docs.

Navbar Colors, Dark Mode and Version Differences

In Bootstrap 5.3, a navbar takes its light or dark scheme from data-bs-theme on the .navbar element, and a bg-* utility sets the background.

VersionLight schemeDark schemeToggler attribute
Bootstrap 4.xnavbar-light bg-lightnavbar-dark bg-darkdata-toggle
5.0 to 5.1navbar-light bg-lightnavbar-dark bg-darkdata-bs-toggle
5.2bg-light (navbar-light deprecated)navbar-dark bg-darkdata-bs-toggle
5.3bg-body-tertiarydata-bs-theme=”dark” (navbar-dark deprecated)data-bs-toggle

Light and dark schemes in 5.3

Bootstrap 5.3.0 reached its stable release on May 30, 2023 (Bootstrap Blog). The data-bs-theme attribute had first shown up in 5.3.0-alpha1 in December 2022.

On a navbar, data-bs-theme=”dark” replaces the deprecated navbar-dark class. It also works on any parent element, so a single value on the html element switches the whole page.

The scheme only sets text colors. The background still comes from a bg-* utility. A neutral dark bar uses bg-dark with border-bottom and border-body. For a colored bar, put bg-primary together with data-bs-theme=”dark”. A pale tint is the odd one out, with a custom background color and data-bs-theme=”light”.

A custom background shifts the contrast the scheme was tuned for, so check the color contrast between link text and the new color before shipping.

One wrinkle in the official docs. When a GitHub issue (#40566) was filed on the Bootstrap repository, the navbar page showed the new data-bs-theme code while the dropdown page still used the old dark variant class. Copy from different component pages and you can end up with both generations in one project.

Renamed classes and attributes from Bootstrap 4

jQuery was dropped in v5.0.0, and Popper moved from v1.x to v2.x (Bootstrap migration guide). Plugin attributes are now namespaced, so data-toggle becomes data-bs-toggle and data-target becomes data-bs-target.

The spacing utilities changed too. .ml-* and .mr-* became .ms-* and .me-*, which is why mr-auto does nothing in a v5 navbar. And .active can no longer sit on a .nav-item. It goes directly on the .nav-link.

A Bootstrap 4 snippet pasted into a v5 page loses its toggle first, because the old data-toggle attribute is no longer read.

CSS and Sass variables

Bootstrap v5.2.0 moved the navbar onto CSS variables, so colors and spacing change without recompiling Sass.

The v5.3.8 source defines 20 –bs-navbar-* variables on .navbar, from –bs-navbar-padding-x to –bs-navbar-toggler-transition. –bs-navbar-color sets link color and –bs-navbar-hover-color sets the hover state.

If you compile Sass, change the $navbar-* variables before compiling, such as $navbar-padding-y (default $spacer * .5) and $navbar-brand-font-size.

Plain CSS overrides work too, and the approach in overriding Bootstrap’s default CSS applies to the navbar like any other component.

Navbar Placement: Fixed, Sticky and Scrollable

Placement comes down to fixed-top, fixed-bottom, sticky-top and sticky-bottom. Fixed pins the navbar to the edge of the browser viewport. Sticky lets it scroll with the page until it reaches that edge.

A fixed navbar leaves the normal document flow, so it overlaps page content and stays visible at all times. The docs say you may need custom CSS, such as padding-top on the body, to prevent that overlap.

A sticky navbar keeps its place in the document flow and reserves its own space. It scrolls with the page, then stays put once it hits the edge.

I’d default to sticky. Reach for fixed only when the navbar has to overlay content from the first pixel, such as a transparent bar over a hero section.

That pattern is usually called sticky navigation, and in Bootstrap it takes a single class, sticky-top.

Bootstrap’s z-index scale puts fixed elements at 1030 and sticky elements at 1020, according to the docs. They also warn that if you change one value you likely need to change them all.

Long menus are a separate problem. Add .navbar-nav-scroll to a .navbar-nav and the menu scrolls inside the collapsed navbar instead of running off the screen. Scrolling starts at 75vh by default.

The docs prose names –bs-navbar-height as the override, but the v5.3.8 source and the docs’ own example both use –bs-scroll-height. Go with the second one.

There’s a drawback that comes from overflow. Setting overflow-y to auto also turns overflow-x into auto, which crops some horizontal content. Above the expand breakpoint the class sets overflow back to visible.

Adding Links, Dropdowns, Forms and Icons

Links, dropdowns, forms and icons all sit inside .navbar-collapse, and Bootstrap’s flex and spacing utilities decide where each group lands.

Active link and Scrollspy

A plain active state is manual. Scrollspy automates it on single-page layouts by toggling .active on any anchor whose target id has scrolled into view.

data-bs-spy=”scroll” and data-bs-target=”#navId” go on the scrollable element, which can be the body. Each link needs a resolvable id target, or the plugin ignores it. If the container holds no focusable element, add tabindex=”0″ so keyboard users can reach it.

rootMargin sets the trigger zone, and data-bs-smooth-scroll=”true” animates link clicks.

Items inside a navbar dropdown highlight too, and an active nested nav marks its parents active.

Scrollspy has run on the Intersection Observer API since v5.2.0. The offset option is deprecated, still parsed into rootMargin, and scheduled for removal in v6, yet one of the v5.3 docs examples still sets data-bs-offset.

Dropdown menus

A navbar dropdown needs a wrapper. Nest a .nav-link.dropdown-toggle and a .dropdown-menu inside a .nav-item.dropdown, because the docs require separate elements for positioning.

The toggle takes data-bs-toggle=”dropdown” and aria-expanded=”false”, and role=”button” is recommended when it’s an anchor. The menu itself is filled with .dropdown-item, .dropdown-divider and .dropdown-header. If a menu sits near the right edge, .dropdown-menu-end right-aligns it.

Items, dividers and headers behave as in a standalone Bootstrap dropdown. Arrow keys move through the .dropdown-item elements and Esc closes the menu.

Bootstrap adds no ARIA menu roles, so any role and aria attributes beyond the basics are yours to write.

Inside the collapsed navbar a dropdown opens inline (position: static). Above the expand breakpoint it floats as an absolutely positioned menu, per the v5.3.8 source.

Alignment with flex utilities

Alignment is a margin question, not a navbar class.

me-auto on .navbar-nav keeps the links left and pushes whatever follows, such as a form, to the right. ms-auto moves the links themselves to the right. mx-auto centers them.

The docs’ own examples add mb-2 mb-lg-0 so the stacked links get bottom spacing only while collapsed.

Forms and icons

A search form is a form with d-flex and role=”search”, an input with form-control and me-2, and a button with a btn variant. When the navbar is mostly a form, the form itself can act as the container.

For icons, the Bootstrap icon set is the project’s own library. The .icon-link helper in 5.3 places and aligns an icon beside link text.

Logos follow a similar pattern. Put an img inside .navbar-brand, with d-inline-block and align-text-top to line it up next to text.

Collapse or Offcanvas for the Mobile Menu?

For a short list of links, collapse is the default and usually enough. Offcanvas earns its place when the menu is long, nested, or just easier to use as a panel over the page.

AttributeCollapseOffcanvas
Layout effectPushes page content down as its height animatesSlides over the page from an edge, with a backdrop
Page scrollPage scrolls as usualBody scroll is off unless data-bs-scroll=”true”
Ways to closeToggler clickClose button, backdrop click or Esc
Default widthFull navbar width400px (Sass default)
Toggle attributedata-bs-toggle=”collapse”data-bs-toggle=”offcanvas”

Offcanvas turns the mobile menu into a drawer, an overlay panel that enters from the left, right, top or bottom edge. Navbars gained support for it in v5.1.0, and the panel sits at z-index 1045, above fixed navbars.

The hamburger menu button stays, but the markup around it changes in a few places.

  • The toggler swaps the collapse attributes for data-bs-toggle=”offcanvas” and a data-bs-target pointing at the panel id.
  • The panel is a div with offcanvas, a placement class such as offcanvas-end, tabindex=”-1″ and aria-labelledby.
  • Its header is .offcanvas-header with an .offcanvas-title and a btn-close carrying data-bs-dismiss=”offcanvas”.
  • .offcanvas-body holds the ul.navbar-nav and any search form.
  • Keep navbar-expand-lg and the panel becomes a normal navbar from lg up. Drop the class and you get a drawer at every width.

By default the panel closes on a backdrop click or Esc, locks body scrolling while open, and allows one offcanvas at a time.

Treat it as a modal dialog and point aria-labelledby at the title, since JavaScript adds role=”dialog” itself. A dismiss button outside the panel works but does not match the ARIA dialog pattern, per the docs.

The Bootstrap docs show two approaches to dark drawers, and they disagree. The navbar page’s example still stacks navbar-dark, bg-dark, text-bg-dark, btn-close-white and dropdown-menu-dark, while the offcanvas page marks that approach deprecated in v5.3.0 in favor of data-bs-theme=”dark”.

In a 5.3 project, use the attribute. The navbar page also warns that offcanvas text can turn illegible in a dark navbar without a dark background.

Why a Bootstrap Navbar Breaks and How to Fix It

Most navbar failures trace back to how the plugins read their attributes.

SymptomCauseFix
Toggler does nothingJS bundle not loaded, or data-toggle used instead of data-bs-toggleLoad bootstrap.bundle.min.js and use the data-bs-* attributes
Toggler still does nothingdata-bs-target and the collapse id differMake both strings identical
Menu never collapses, or never expands.navbar-expand with no suffix, or no expand class at allUse one navbar-expand-{breakpoint} class on .navbar
Dropdown does not opendata-bs-toggle=”dropdown” missing, or plugin JavaScript not loadedAdd the attribute and load the bundle
Menu stays open after a link clickAn in-page link does not reload the page, so nothing closes the collapseCall hide on the Collapse instance in a click handler

Toggler and collapse failures

The Collapse plugin reads data-bs-toggle and data-bs-target. Bootstrap 4 attributes get skipped.

Padding on .navbar-collapse causes its own trouble. The docs rule it out on a .collapse element because of how CSS handles height animation. Wrap the content in an inner element and pad that instead.

For the menu that stays open after a click, call bootstrap.Collapse.getOrCreateInstance(el, { toggle: false }).hide() in the link’s click handler.

The toggle option defaults to true, so a fresh instance built with defaults toggles the element on creation. Methods are also asynchronous, and a call made during a transition is ignored.

Dropdown failures

The dropdown documentation adds a qualifier to the Popper requirement. Popper is not used to position dropdowns in navbars, because dynamic positioning is not required there.

The same page still says to load Popper or use the bundle, so the bundle stays the safe choice.

  • data-bs-toggle=”dropdown” is also relied on to close dropdowns at the application level, so always include it
  • A dropdown closes on clicks inside or outside the menu by default, so a form that should stay open needs data-bs-auto-close=”outside”
  • data-bs-display=”static” is not needed in a navbar

Where the navbar stops being enough

Bootstrap dropdowns open on click, never on hover. The docs call that an intentional design decision.

The v5.3 docs describe no submenu pattern either. An answer recorded in the Bootstrap 4 issue tracker (#21026, October 2016) says nested dropdowns have not been supported since v3.

Hover menus and multilevel submenus therefore mean custom code, such as pure CSS dropdown menus or script-driven behavior layered on the plugin.

If those patterns are central to the design, weigh the patching cost before committing to the Bootstrap navbar.

Bootstrap Navbar FAQ

Is a navbar the same thing as a nav in Bootstrap?

No. The .nav component is the base for link lists such as tabs and pills, while .navbar is a header wrapper with its own .navbar-nav modifier and toggler behavior.

Navbar links reuse .nav-link, but .navbar-nav sets its own flex layout, so the .nav class is not needed (v5.3.8 source).

How can I make a Bootstrap navbar transparent?

Leave off the bg-* class. The .navbar rule sets no background color of its own, so the page shows through, and bg-transparent does the same explicitly.

Over a dark hero image, add data-bs-theme=”dark” so the link text turns light.

How do I change the hamburger icon color?

Text color utilities won’t touch it, because the toggler icon is an SVG background image.

Override –bs-navbar-toggler-icon-bg with your own SVG, or switch the navbar scheme with data-bs-theme, which swaps in the stored dark icon. The border color has its own variable, –bs-navbar-toggler-border-color.

Which setting controls the height of a navbar?

Vertical padding does. Set –bs-navbar-padding-y on the .navbar, or add a py-* utility class.

The brand and the links carry their own padding as well, so a tall logo inside .navbar-brand stretches the bar too.

Which Bootstrap Navbar Setup Fits a New Project?

A new project should start on the v5.3 pattern. That means bg-body-tertiary for the background, data-bs-theme for color, and one navbar-expand-lg class with the bundled JavaScript.

Wire it in this order, since each step depends on the one before:

  • Breakpoint class
  • Toggler id and data-bs-target pair
  • Close handler for in-page links

The breakpoint comes first because it decides which layout every later rule targets. The close handler only matters on single-page layouts, since a full page load already resets the menu.

This position was verified against v5.3.8 in October 2026. That source schedules navbar-light for removal in v6.0.0, so a Bootstrap 6 release would change the class list.

The same data-bs-* attributes carry over to other Bootstrap components, the natural next area to learn.