Snippets Menu

Bootstrap 5 Off-Canvas Menu with Slide-In Navigation

A slide-in navigation panel opened from a menu button, with icon links, search and an account card. The panel can be dismissed with Esc, the backdrop or the close button and can slide from either side.

Bootstrap 5 No jQuery Jun 2019 2.4K views

<section class="wdw-stage">
  <div class="container" style="max-width: 1040px">
    <div class="wdw-card overflow-hidden">
      <header class="d-flex align-items-center justify-content-between gap-3 px-3 px-md-4 py-3 border-bottom">
        <div class="d-flex align-items-center gap-3">
          <button class="btn btn-outline-primary rounded-pill px-3" type="button" data-bs-toggle="offcanvas" data-bs-target="#siteMenu" aria-controls="siteMenu">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h10"/></svg>
            <span>Menu</span>
          </button>
          <span class="fw-bold fs-5 text-body-emphasis d-none d-sm-inline">Northwind</span>
        </div>
        <a href="#" class="btn btn-primary rounded-pill px-4">Get started</a>
      </header>

      <div class="row g-0 align-items-stretch">
        <div class="col-lg-7 p-4 p-md-5">
          <span class="wdw-eyebrow mb-3">Off-canvas navigation</span>
          <h1 class="wdw-heading display-5 mb-3">A menu that slides in, then gets out of the way.</h1>
          <p class="wdw-muted fs-5 mb-4">Tap the menu button to open a side panel with your main links, search and account actions. Press Esc, tap the backdrop or hit the close button to dismiss it.</p>
          <div class="d-flex flex-wrap gap-2">
            <button class="btn btn-primary rounded-pill px-4 flex-fill flex-sm-grow-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#siteMenu" aria-controls="siteMenu">Open menu</button>
            <button class="btn btn-outline-primary rounded-pill px-4 flex-fill flex-sm-grow-0" type="button" id="menuSideToggle" aria-pressed="false">Switch to right side</button>
          </div>
        </div>
        <div class="col-lg-5 wdw-aurora p-4 p-md-5 d-flex flex-column align-items-center justify-content-center gap-3">
          <div class="wdw-mini bg-body text-body rounded-4 shadow-lg p-3 w-100" aria-hidden="true">
            <div class="d-flex align-items-center justify-content-between mb-3">
              <span class="fw-bold">Northwind</span>
              <span class="wdw-mini-x">×</span>
            </div>
            <div class="wdw-mini-search rounded-pill px-3 py-2 small mb-2">Search the site</div>
            <div class="d-flex flex-column gap-1 small fw-semibold">
              <div class="rounded-3 px-3 py-2 text-bg-primary">Home</div>
              <div class="rounded-3 px-3 py-2">Projects</div>
              <div class="rounded-3 px-3 py-2 d-flex justify-content-between">Messages <span class="badge rounded-pill text-bg-primary">4</span></div>
              <div class="rounded-3 px-3 py-2">Settings</div>
            </div>
            <div class="d-flex align-items-center gap-2 mt-3 p-2 rounded-3 bg-body-tertiary">
              <span class="rounded-circle bg-primary-subtle d-inline-block" style="width:28px;height:28px"></span>
              <span class="small fw-semibold">Mara Ellis</span>
            </div>
          </div>
          <div class="d-flex gap-2 w-100">
            <div class="wdw-key rounded-4 p-2 px-3 flex-fill small"><strong>Esc</strong> closes</div>
            <div class="wdw-key rounded-4 p-2 px-3 flex-fill small"><strong>Tab</strong> stays inside</div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="offcanvas offcanvas-start wdw-menu" tabindex="-1" id="siteMenu" aria-labelledby="siteMenuLabel">
    <div class="offcanvas-header px-4 pt-4">
      <h2 class="offcanvas-title fs-5 fw-bold" id="siteMenuLabel">Northwind</h2>
      <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close menu"></button>
    </div>
    <div class="offcanvas-body px-4 d-flex flex-column gap-4">
      <label class="visually-hidden" for="menuSearch">Search</label>
      <input id="menuSearch" type="search" class="form-control" placeholder="Search the site">
      <nav aria-label="Main">
        <ul class="nav nav-pills flex-column gap-1">
          <li class="nav-item"><a class="nav-link active d-flex align-items-center gap-3" href="#" aria-current="page"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 11l9-8 9 8v9a1 1 0 0 1-1 1h-5v-6H9v6H4a1 1 0 0 1-1-1z"/></svg>Home</a></li>
          <li class="nav-item"><a class="nav-link d-flex align-items-center gap-3" href="#"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg>Projects</a></li>
          <li class="nav-item"><a class="nav-link d-flex align-items-center gap-3" href="#"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0M16 4.5a3.5 3.5 0 0 1 0 7M18 14a6.5 6.5 0 0 1 3.5 6"/></svg>Team</a></li>
          <li class="nav-item"><a class="nav-link d-flex align-items-center gap-3" href="#"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 5h16v11H8l-4 4z"/></svg>Messages<span class="badge rounded-pill text-bg-primary ms-auto">4</span></a></li>
          <li class="nav-item"><a class="nav-link d-flex align-items-center gap-3" href="#"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M19 12a7 7 0 0 0-.1-1.2l2-1.5-2-3.4-2.3 1a7 7 0 0 0-2-1.2L14.2 3h-4l-.4 2.7a7 7 0 0 0-2 1.2l-2.3-1-2 3.4 2 1.5a7 7 0 0 0 0 2.4l-2 1.5 2 3.4 2.3-1a7 7 0 0 0 2 1.2l.4 2.7h4l.4-2.7a7 7 0 0 0 2-1.2l2.3 1 2-3.4-2-1.5c.1-.4.1-.8.1-1.2z"/></svg>Settings</a></li>
        </ul>
      </nav>
      <div class="mt-auto d-flex align-items-center gap-3 p-3 rounded-4 bg-body-tertiary">
        <img src="https://i.pravatar.cc/80?img=47" width="44" height="44" class="rounded-circle" alt="Profile photo of Mara Ellis">
        <div class="lh-sm"><div class="fw-semibold">Mara Ellis</div><small class="wdw-muted">[email protected]</small></div>
      </div>
    </div>
  </div>
</section>

Built on Bootstrap 5.3.8 with plain JavaScript — no jQuery. Supports light and dark mode via data-bs-theme.

Free to use in personal and commercial projects under the MIT license.