Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Offcanvas

Offcanvas is a panel that slides in from the edge of the screen over the page. It is like a modal, but the panel is attached to an edge and is usually tall. It holds the menu on a phone, a cart, filters. In the admin dashboard it is the main way to hide the sidebar on a narrow screen.

A panel opened by a button

The panel is an offcanvas offcanvas-start block with an id: an offcanvas-header with a title and a close cross, and an offcanvas-body. A button opens it with data-bs-toggle="offcanvas":

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
 
<div style="min-height: 260px">
  <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebar" aria-controls="sidebar">
    Menu
  </button>
</div>
 
<div class="offcanvas offcanvas-start" tabindex="-1" id="sidebar" aria-labelledby="sidebarLabel">
  <div class="offcanvas-header">
    <h5 class="offcanvas-title" id="sidebarLabel">Tasko Admin</h5>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
  </div>
  <div class="offcanvas-body">
    <ul class="nav flex-column">
      <li class="nav-item"><a class="nav-link" href="#">Overview</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Users</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Settings</a></li>
    </ul>
  </div>
</div>
 
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

Click "Menu" and a white panel with links slides in from the left while the page dims. It closes with the cross, the Escape key or a click on the dimmed area.

Which side

ClassSlides in from
offcanvas-startThe left
offcanvas-endThe right
offcanvas-topThe top
offcanvas-bottomThe bottom

The data-bs-scroll="true" attribute on the panel lets the page keep scrolling, and data-bs-backdrop="false" removes the dimming.

A menu that is always visible on wide screens

The offcanvas-lg class instead of offcanvas makes the panel responsive: below 992 pixels it is a sliding panel, from 992 it is a regular block in its place. This is exactly what the admin sidebar needs:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
 
<div style="min-height: 260px">
  <button class="btn btn-outline-secondary d-lg-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#adminMenu" aria-controls="adminMenu">
    Menu
  </button>
 
  <div class="offcanvas-lg offcanvas-start" tabindex="-1" id="adminMenu" aria-labelledby="adminMenuLabel">
    <div class="offcanvas-header">
      <h5 class="offcanvas-title" id="adminMenuLabel">Sections</h5>
      <button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#adminMenu" aria-label="Close"></button>
    </div>
    <div class="offcanvas-body">
      <ul class="nav flex-column">
        <li class="nav-item"><a class="nav-link" href="#">Overview</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Orders</a></li>
      </ul>
    </div>
  </div>
</div>
 
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

In the narrow preview you only see the "Menu" button, and the panel slides in on click. On a wide screen the button is hidden by d-lg-none, and the links sit right on the page. The same variants exist for other breakpoints: offcanvas-md, offcanvas-xl.

Common mistake

Copying the close cross from a regular panel into a responsive offcanvas-lg one without data-bs-target. A button with data-bs-dismiss="offcanvas" looks for the nearest parent with the offcanvas class, but the responsive panel has a different class, offcanvas-lg, so the cross does nothing. In a responsive panel give the close button data-bs-target="#adminMenu", as in the example above.

To open a panel from code, use bootstrap.Offcanvas.getOrCreateInstance('#sidebar').show().

Thanks for reading!

Donate to the site — we work hard for you.