Offcanvas

Integrate concealed sidebars into projects for navigation, shopping carts, and various other uses, leveraging a few classes and the JavaScript plugin.

Class Name Type Description
offcanvas Component Offcanvas container
offcanvas-sm Component Make offcanvas under sm breakpoint
offcanvas-md Component Make offcanvas under md breakpoint
offcanvas-lg Component Make offcanvas under lg breakpoint
offcanvas-xl Component Make offcanvas under xl breakpoint
offcanvas-xxl Component Make offcanvas under 2xl breakpoint
offcanvas-header Inner Header section
offcanvas-title Inner Header title
offcanvas-body Inner Body content
offcanvas-start Modifier Opens from left
offcanvas-end Modifier Opens from right
offcanvas-top Modifier Opens from top
offcanvas-bottom Modifier Opens from bottom

How it works

Offcanvas functions as a sidebar component, capable of being toggled via JavaScript to emerge from the viewport’s left, right, top, or bottom edges. Buttons or anchors serve as triggers, attached to specific elements for toggling, and data attributes are employed to invoke the JavaScript.

  • Offcanvas shares certain JavaScript code with modals; conceptually, they exhibit strong similarities, yet they remain distinct plugins.
  • Correspondingly, some css variables governing offcanvas styles and dimensions are inherited from modal variables.
  • When displayed, offcanvas includes a default backdrop which, when clicked, conceals the offcanvas.
  • Similar to modals, only a single offcanvas element can be shown at any given time.

Important Note: Due to how CSS manages animations, the use of margin or translate on an .offcanvas element is not supported. Instead, utilize the class as an independent wrapping element.

Example

The offcanvas component can be triggered using either an <a> element with href or a <button> element with data-bs-target.

  • Clicking a trigger shows the offcanvas panel
  • The panel can be hidden by clicking the close button (data-bs-dismiss="offcanvas") or by interacting outside the panel.

HTML

<a class="btn btn-primary" data-bs-toggle="offcanvas" href="#offcanvasExample" role="button" aria-controls="offcanvasExample">
  Link with href
</a>
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
  Button with data-bs-target
</button>
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="offcanvasExampleLabel">Offcanvas</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    <div class="list-group bg-transparent p-0">
      <a href="#" class="list-group-item list-group-item-action rounded-md active" aria-current="true">List Item One</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Two</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Three</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Four</a>
    </div>
  </div>
</div>

Body scrolling

When an offcanvas and its backdrop are visible, scrolling on the <body> element is disabled. To allow <body> scrolling, use the data-bs-scroll attribute.

HTML

<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasScrolling" aria-controls="offcanvasScrolling">Enable body scrolling</button>

<div class="offcanvas offcanvas-start" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1" id="offcanvasScrolling" aria-labelledby="offcanvasScrollingLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="offcanvasScrollingLabel">Offcanvas</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    <div class="list-group bg-transparent p-0">
      <a href="#" class="list-group-item list-group-item-action rounded-md active" aria-current="true">List Item One</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Two</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Three</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Four</a>
    </div>
  </div>
</div>

Body scrolling and backdrop

Body scrolling can also be enabled along with a backdrop.

HTML

<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasWithBothOptions" aria-controls="offcanvasWithBothOptions">Enable both scrolling & backdrop</button>

<div class="offcanvas offcanvas-start" data-bs-scroll="true" tabindex="-1" id="offcanvasWithBothOptions" aria-labelledby="offcanvasWithBothOptionsLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="offcanvasWithBothOptionsLabel">Offcanvas</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    <div class="list-group bg-transparent p-0">
      <a href="#" class="list-group-item list-group-item-action rounded-md active" aria-current="true">List Item One</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Two</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Three</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Four</a>
    </div>
  </div>
</div>

Static backdrop

When backdrop is set to static, the offcanvas does not close when clicking outside of it.

HTML

<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#staticBackdrop" aria-controls="staticBackdrop">Toggle static offcanvas</button>

<div class="offcanvas offcanvas-start" data-bs-backdrop="static" tabindex="-1" id="staticBackdrop" aria-labelledby="staticBackdropLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="staticBackdropLabel">Offcanvas</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    <div class="list-group bg-transparent p-0">
      <a href="#" class="list-group-item list-group-item-action rounded-md active" aria-current="true">List Item One</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Two</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Three</a>
      <a href="#" class="list-group-item list-group-item-action rounded-md">List Item Four</a>
    </div>
  </div>
</div>

Responsive

Responsive offcanvas classes hide content below a specified breakpoint, while showing it above that breakpoint. For example, .offcanvas-lg hides the offcanvas on screens smaller than lg, but displays it on lg and larger screens. Classes are available for all breakpoints:

  • .offcanvas
  • .offcanvas-sm
  • .offcanvas-md
  • .offcanvas-lg
  • .offcanvas-xl
  • .offcanvas-xxl

To create a responsive offcanvas, replace the .offcanvas base class with a responsive variant, and ensure the close button includes an explicit data-bs-target.

Responsive offcanvas

This is content within responsive offcanvas. The Responsive Offcanvas component adapts its behavior based on the screen size. It behaves like a sliding drawer on mobile and a static sidebar on larger breakpoints (lg and up)

HTML

<button class="btn btn-primary lg:hidden" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasResponsive" aria-controls="offcanvasResponsive">Toggle offcanvas</button>

<div class="alert alert-subtle-info hidden lg:block mb-4">Resize your browser to show the responsive offcanvas toggle.</div>

<div class="offcanvas-lg offcanvas-start" tabindex="-1" id="offcanvasResponsive" aria-labelledby="offcanvasResponsiveLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="offcanvasResponsiveLabel">Responsive offcanvas</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close" data-bs-target="#offcanvasResponsive">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    <p class="mb-0">This is content within responsive offcanvas. The Responsive Offcanvas component adapts its behavior based on the screen size. It behaves like a sliding drawer on mobile and a static sidebar on larger breakpoints (lg and up)</p>
  </div>
</div>

Placement

Offcanvas components have no default placement. Add one of the following modifier classes to define placement:

  • .offcanvas-start places offcanvas on the left
  • .offcanvas-end places offcanvas on the right
  • .offcanvas-top places offcanvas on the top
  • .offcanvas-bottom places offcanvas on the bottom

Try the top, right, and bottom examples below.

Offcanvas Top
...

HTML

<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasTop" aria-controls="offcanvasTop">Toggle top offcanvas</button>

<div class="offcanvas offcanvas-top" tabindex="-1" id="offcanvasTop" aria-labelledby="offcanvasTopLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="offcanvasTopLabel">Offcanvas Top</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    ...
  </div>
</div>
Offcanvas Right
...

HTML

<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight">Toggle right offcanvas</button>

<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasRight" aria-labelledby="offcanvasRightLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="offcanvasRightLabel">Offcanvas Right</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    ...
  </div>
</div>
Offcanvas Bottom
...

HTML

<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasBottom" aria-controls="offcanvasBottom">Toggle bottom offcanvas</button>

<div class="offcanvas offcanvas-bottom" tabindex="-1" id="offcanvasBottom" aria-labelledby="offcanvasBottomLabel">
  <div class="offcanvas-header">
    <h6 class="offcanvas-title font-semibold" id="offcanvasBottomLabel">Offcanvas Bottom</h6>
    <button type="button" class="btn btn-icon ms-auto" data-bs-dismiss="offcanvas" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z" stroke-width="0.5" stroke="currentColor"/></svg>
    </button>
  </div>
  <div class="offcanvas-body">
    ...
  </div>
</div>

CSS variables

The offcanvas component is built using a set of CSS variables. These variables provide flexibility for customizing styles.

.offcanvas {
  --offcanvas-zindex: 1045;
  --offcanvas-width: 20rem;
  --offcanvas-height: 30vh;
  --offcanvas-padding-x: --spacing(4);
  --offcanvas-padding-y: --spacing(4);
  --offcanvas-color: var(--text-color-default);
  --offcanvas-bg: var(--background-color-subtle);
  --offcanvas-border-width: 1px;
  --offcanvas-border-color: var(--border-color-base);
  --offcanvas-box-shadow: var(--shadow-xl);
  --offcanvas-transition-duration: 0.3s;
  --offcanvas-title-line-height: 1.5;
}

Usage

The offcanvas plugin employs specific classes and attributes to manage its primary functions:

  • .offcanvas hides the content.
  • .offcanvas.show shows the content.
  • .offcanvas-start hides the offcanvas on the left.
  • .offcanvas-end hides the offcanvas on the right.
  • .offcanvas-top hides the offcanvas on the top.
  • .offcanvas-bottom hides the offcanvas on the bottom.

Include a dismiss button with the data-bs-dismiss="offcanvas" attribute; this triggers the associated JavaScript functionality. Ensure that a <button> element is used for this purpose to ensure proper behavior across all devices.

Via data attributes

Toggle

To automatically control an offcanvas element, add data-bs-toggle="offcanvas" and either a data-bs-target or href to the controlling element. The data-bs-target attribute accepts a CSS selector, indicating which offcanvas element to apply the functionality to. Ensure the offcanvas class is also added to the offcanvas element. To have it open by default, include the show class as well.

Dismiss

Dismissal of an offcanvas can be accomplished using the data-bs-dismiss attribute on a button located within the offcanvas, as demonstrated below:

<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>

Alternatively, dismissal can be achieved from a button outside the offcanvas by including the data-bs-target attribute, as illustrated:

<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#my-offcanvas" aria-label="Close"></button>

Via JavaScript

Use JavaScript in the familiar pattern of Bootstrap’s plugins with full additional TypeScript Support.

Manual enablement is achieved with the following JavaScript:

const offcanvasElementList = document.querySelectorAll('.offcanvas')
const offcanvasList = [...offcanvasElementList].map(offcanvasEl => new hummingbird.Offcanvas(offcanvasEl))

Options

Options can be provided through data attributes or via JavaScript. When using data-bs-attributes, append the option’s name (e.g., data-bs-animation="{value}"). It is crucial to convert “camelCase” option names to “kebab-case” when passing options via data attributes. For instance, use data-bs-custom-class="beautifier" rather than data-bs-customClass="beautifier".

Offcanvas component support data-bs-config data attribute. This attribute can contain simple component configurations as a JSON string. If an element has both data-bs-config='{"delay":0, "title":123}' and data-bs-title="456" attributes, the final title value will be 456, as separate data attributes override values provided within data-bs-config. Additionally, existing data attributes can also house JSON values, such as data-bs-delay='{"show":0,"hide":150}'.

The ultimate configuration object results from merging data-bs-config, individual data-bs-attributes, and JavaScript objects where the latest provided key-value pair takes precedence over others.

NameTypeDefaultDescription
backdropboolean or the string statictrueDetermines whether a backdrop is applied to the body while the offcanvas is open. Alternatively, specifying static creates a backdrop that does not close the offcanvas when clicked.
keyboardbooleantrueThis option enables closing the offcanvas when the escape key is pressed.
scrollbooleanfalseThis option allows body scrolling while the offcanvas is open.

Methods

Content can be activated as an offcanvas element by providing an optional options object.

An offcanvas instance can be created using the constructor, for example:

const bsOffcanvas = new hummingbird.Offcanvas('#myOffcanvas')
MethodDescription
disposeDestroys an offcanvas element.
getInstanceA static method for retrieving the offcanvas instance linked to a specific DOM element.
getOrCreateInstanceA static method for either retrieving an existing offcanvas instance associated with a DOM element or creating a new one if it has not been initialized.
hideConceals an offcanvas element, returning control to the caller before the offcanvas element has actually been hidden (i.e., before the hidden.bs.offcanvas event occurs).
showDisplays an offcanvas element, returning control to the caller before the offcanvas element has actually been shown (i.e., before the shown.bs.offcanvas event occurs).
toggleSwitches the state of an offcanvas element between shown and hidden, returning control to the caller before the offcanvas element has actually been shown or hidden (i.e., before the shown.bs.offcanvas or hidden.bs.offcanvas event occurs).

Events

The offcanvas class within Bootstrap provides a series of events for integrating with offcanvas functionality.

Event TypeDescription
hide.bs.offcanvasThis event triggers immediately upon the hide method’s invocation.
hidden.bs.offcanvasThis event triggers after an offcanvas element has completed its transition to a hidden state from the user’s view (it awaits the completion of CSS transitions).
hidePrevented.bs.offcanvasThis event triggers when the offcanvas is displayed, its backdrop is static, and an external click occurs. It also triggers when the escape key is pressed while the keyboard option is set to false.
show.bs.offcanvasThis event triggers immediately when the show instance method is called.
shown.bs.offcanvasThis event triggers once an offcanvas element has become visible to the user (it awaits the completion of CSS transitions).
const myOffcanvas = document.getElementById('myOffcanvas')
myOffcanvas.addEventListener('hidden.bs.offcanvas', event => {
  // perform actions...
})