Offcanvas

Build hidden sidebars into your project for navigation, shopping carts, and more with a Offcanvas components.

On this page

How it works

Offcanvas is a sidebar component that can be toggled to appear from the left, right, top, or bottom edge of the viewport.

When shown, offcanvas includes a default backdrop that can be clicked to hide the offcanvas.

Similar to modals, only one offcanvas can be shown at a time.

Heads up! Given how CSS handles animations, you cannot use margin or translate on an Offcanvas element.

Instead, use the class as an independent wrapping element.

Examples

Offcanvas components

Below is an offcanvas example that is shown by default (via show on Offcanvas).

Offcanvas includes support for a header with a close button and an optional body class for some initial padding.

We suggest that you include offcanvas headers with dismiss actions whenever possible, or provide an explicit dismiss action.

Offcanvas
Content for the offcanvas goes here. You can place just about any Bootstrap component or custom elements here.
vue
<template>
  <Offcanvas
    placement="start"
    show
    :backdrop="false"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Offcanvas</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      Content for the offcanvas goes here. You can place just about any
      Bootstrap component or custom elements here.
    </OffcanvasBody>
  </Offcanvas>
</template>

Live demo

Use the buttons below to show and hide an offcanvas element via JavaScript that toggles the show attribute on an element with the Offcanvas component.

  • Offcanvas hides content (default)
  • show shows content

You can use a link with the href attribute, or a button with the target attribute. In both cases, the toggle="offcanvas" is required.

vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasExample"
  >
    Launch demo modal
  </b-button>
  <Offcanvas
    id="offcanvasExample"
    placement="start"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Offcanvas</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <div>
        Some text as placeholder. In real life you can have the elements you
        have chosen. Like, text, images, lists, etc.
      </div>
      <Dropdown margin="t-3">
        <DropdownToggle button="secondary">
          Droppdown button
        </DropdownToggle>
        <DropdownMenu>
          <DropdownItem>Action</DropdownItem>
          <DropdownItem>Another action</DropdownItem>
          <DropdownItem>Something else here</DropdownItem>
        </DropdownMenu>
      </Dropdown>
    </OffcanvasBody>
  </Offcanvas>
</template>

Body scrolling

vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasBodyScrolling"
  >
    Launch demo modal
  </b-button>
  <Offcanvas
    id="offcanvasBodyScrolling"
    placement="start"
    scroll
    :backdrop="false"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <div>
        Some text as placeholder. In real life you can have the elements you
        have chosen. Like, text, images, lists, etc.
      </div>
      <Dropdown margin="t-3">
        <DropdownToggle button="secondary">
          Droppdown button
        </DropdownToggle>
        <DropdownMenu>
          <DropdownItem>Action</DropdownItem>
          <DropdownItem>Another action</DropdownItem>
          <DropdownItem>Something else here</DropdownItem>
        </DropdownMenu>
      </Dropdown>
    </OffcanvasBody>
  </Offcanvas>
</template>

Body scrolling and backdrop

vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasBodyScrollingBackdrop"
  >
    Launch demo modal
  </b-button>
  <Offcanvas
    id="offcanvasBodyScrollingBackdrop"
    placement="start"
    scroll
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <div>
        Some text as placeholder. In real life you can have the elements you
        have chosen. Like, text, images, lists, etc.
      </div>
      <Dropdown margin="t-3">
        <DropdownToggle button="secondary">
          Droppdown button
        </DropdownToggle>
        <DropdownMenu>
          <DropdownItem>Action</DropdownItem>
          <DropdownItem>Another action</DropdownItem>
          <DropdownItem>Something else here</DropdownItem>
        </DropdownMenu>
      </Dropdown>
    </OffcanvasBody>
  </Offcanvas>
</template>

Static backdrop

vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasStaticBackdrop"
  >
    Launch demo modal
  </b-button>
  <Offcanvas
    id="offcanvasStaticBackdrop"
    placement="start"
    backdrop="static"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <div>
        Some text as placeholder. In real life you can have the elements you
        have chosen. Like, text, images, lists, etc.
      </div>
      <Dropdown margin="t-3">
        <DropdownToggle button="secondary">
          Droppdown button
        </DropdownToggle>
        <DropdownMenu>
          <DropdownItem>Action</DropdownItem>
          <DropdownItem>Another action</DropdownItem>
          <DropdownItem>Something else here</DropdownItem>
        </DropdownMenu>
      </Dropdown>
    </OffcanvasBody>
  </Offcanvas>
</template>

Responsive

vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasResponsive"
    display="lg-none"
  >
    Toggle offcanvas
  </b-button>
  <Alert
    theme="info"
    display="none lg-block"
  >
    Resize your browser to show the responsive offcanvas toggle.
  </Alert>

  <Offcanvas
    id="offcanvasResponsive"
    placement="end"
    type="lg"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Responsive offcanvas</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <b-p margin="b-0">
        This is content within an <code>.offcanvas-lg</code>.
      </b-p>
    </OffcanvasBody>
  </Offcanvas>
</template>

Placement

There's no default placement for offcanvas components, so you must add one of the modifier classes below;

  • Offcanvas-start places offcanvas on the left of the viewport (shown above)
  • Offcanvas-end places offcanvas on the right of the viewport
  • Offcanvas-top places offcanvas on the top of the viewport
  • Offcanvas-bottom places offcanvas on the bottom of the viewport

Try the top, right, and bottom examples out below.

vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasTop"
  >
    Launch demo modal
  </b-button>
  <Offcanvas
    id="offcanvasTop"
    placement="top"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>...</OffcanvasBody>
  </Offcanvas>
</template>
vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasRight"
  >
    Toggle right offcanvas
  </b-button>
  <Offcanvas
    id="offcanvasRight"
    placement="end"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>...</OffcanvasBody>
  </Offcanvas>
</template>
vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasBottom"
  >
    Toggle bottom offcanvas
  </b-button>
  <Offcanvas
    id="offcanvasBottom"
    placement="bottom"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody small>
      ...
    </OffcanvasBody>
  </Offcanvas>
</template>

Backdrop

Scrolling the <body> element is disabled when an offcanvas and its backdrop are visible. Use the scroll attribute to toggle <body> scrolling and backdrop attribute to toggle the backdrop.

vue
<template>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasScrolling"
  >
    Enable body scrolling
  </b-button>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasWithBackdrop"
  >
    Enable backdrop (default)
  </b-button>
  <b-button
    button="primary"
    toggle="offcanvas"
    target="#offcanvasScrolling"
  >
    Enable both scrolling & backdrop
  </b-button>
  <Offcanvas
    id="offcanvasScrolling"
    placement="start"
    scroll
    backdrop="false"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <p>Try scrolling the rest of the page to see this option in action.</p>
    </OffcanvasBody>
  </Offcanvas>
  <Offcanvas
    id="offcanvasWithBackdrop"
    placement="start"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <p>Try scrolling the rest of the page to see this option in action.</p>
    </OffcanvasBody>
  </Offcanvas>
  <Offcanvas
    id="offcanvasWithBothOptions"
    placement="start"
    scroll
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <p>Try scrolling the rest of the page to see this option in action.</p>
    </OffcanvasBody>
  </Offcanvas>
</template>

Usage

The offcanvas plugin utilizes a few classes and attributes to handle the heavy lifting:

  • placement hides the content
  • placement="show" shows the content
  • placement="start" hides the offcanvas on the left
  • placement="end" hides the offcanvas on the right
  • placement="top" hides the offcanvas on the top
  • placement="bottom" hides the offcanvas on the bottom

Add a dismiss button with the dismiss="offcanvas" attribute, which triggers the JavaScript functionality. Be sure to use the BvBbutton component with it for proper behavior across all devices.

Methods

Demo

vue
<template>
    <b-button type="button" button="primary" @click="toggleClicked">
        Toggle
    </b-button>
    <b-button type="button" button="primary" @click="showClicked">
        Show
    </b-button>
    <Offcanvas
    placement="bottom"
    scroll
    backdrop="false"
    ref="demoOffcanvas"
  >
    <OffcanvasHeader>
      <OffcanvasTitle>Colored with scrolling</OffcanvasTitle>
      <CloseButton dismiss="offcanvas" />
    </OffcanvasHeader>
    <OffcanvasBody>
      <p>Try scrolling the rest of the page to see this option in action.</p>
      <b-button type="button" button="primary" @click="hideClicked">
        Hide
      </b-button>
    </OffcanvasBody>
  </Offcanvas>
</template>
<script setup lang="ts">
const demoOffcanvas = ref(null)

const toggleClicked = () => {
    if(demoOffcanvas.value) {
        demoOffcanvas.value.toggle()
    }
}
const hideClicked = () => {
    if(demoOffcanvas.value) {
        demoOffcanvas.value.hide()
    }
}
const showClicked = () => {
    if(demoOffcanvas.value) {
        demoOffcanvas.value.show()
    }
}
</script>