Offcanvas Offcanvas.js
Add hidden dialog sidebars that slide into view from the edge of the page or container.
How It Works
Offcanvas is a component to create sidebars that can be toggled using JavaScript to appear from the edges of a viewport or container.
- Buttons, or anchors, are used to toggle the associated offcanvas element.
- Offcanvas shares much of the same functionality as modals, but operates slightly differently.
- By default, offcanvas also uses a backdrop when showing that can be clicked to hide the offcanvas.
- Only one offcanvas should be shown at a time.
Heads up! You should not use margin
or translate
on an .offcanvas
element as this will interfere with the CSS animations. Instead, use the class as an independent wrapping element.
Examples
Offcanvas Components
Below is an offcanvas example that is shown by default (via .in
on .offcanvas
). Offcanvas includes support for a header with a close button, an optional body class for some initial padding
and overflow
handling. Also available is a completely optional footer container with some available padding
and end-aligned content. The offcanvas body will automatically grow to fill the available height.
We suggest that you include offcanvas headers with dismiss actions whenever possible, or provide an explicit dismiss action.
Offcanvas
<div class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Content for the offcanvas goes here. You can place just about any component or custom element here.
</div>
<div class="offcanvas-footer">
Offcanvas footer
</div>
</div>
Live Demo
Use the buttons below to show and hide an offcanvas element via JavaScript that toggles the .in
class on an element with the .offcanvas
class.
.offcanvas
hides content (default).offcanvas.in
shows content
You can use a link with the href
attribute, or a button with the data-cfw-offcanvas-target
attribute. In both cases, the data-cfw="offcanvas"
attribute is required.
Offcanvas
Some placeholder text. You can include elements here such as, text, images, links, and even more complex components.
<button type="button" class="btn btn-primary" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasData">
Button with data-*-target
</button>
<div id="offcanvasData" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
<p>Some placeholder text. You can include elements here such as, text, images, links, and even more complex components.</p>
<div class="dropdown">
<button type="button" class="btn btn-secondary" data-cfw="dropdown">
Dropdown <span class="caret" aria-hidden="true"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
</ul>
</div>
</div>
<div class="offcanvas-footer">
Offcanvas footer
</div>
</div>
Offcanvas
Some placeholder text. You can include elements here such as, text, images, links, and even more complex components.
<a role="button" class="btn btn-primary" data-cfw="offcanvas" href="#offcanvasHref">
Link with href
</a>
<div id="offcanvasHref" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
<p>Some placeholder text. You can include elements here such as, text, images, links, and even more complex components.</p>
<div class="dropdown">
<button type="button" class="btn btn-secondary" data-cfw="dropdown">
Dropdown <span class="caret" aria-hidden="true"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
</ul>
</div>
</div>
<div class="offcanvas-footer">
Offcanvas footer
</div>
</div>
Placement
There is no default placement for an offcanvas components, so you must add one of the following modifier classes;
.offcanvas-start
- start edge of the viewport.offcanvas-end
- end edge of the viewport.offcanvas-top
- top edge of the viewport.offcanvas-bottom
- bottom edge of the viewport
Offcanvas start
Offcanvas end
Offcanvas top
Offcanvas bottom
<!-- Toggle buttons -->
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasStart">Offcanvas start</button>
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasEnd">Offcanvas end</button>
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasTop">Offcanvas top</button>
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasBottom">Offcanvas bottom</button>
<!-- Directional examples -->
<div id="offcanvasStart" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas start</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Offcanvas content
</div>
</div>
<div id="offcanvasEnd" class="offcanvas offcanvas-end">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas end</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Offcanvas content
</div>
</div>
<div id="offcanvasTop" class="offcanvas offcanvas-top">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas top</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Offcanvas content
</div>
</div>
<div id="offcanvasBottom" class="offcanvas offcanvas-bottom">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas bottom</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Offcanvas content
</div>
</div>
Backdrop and Scrolling
Scrolling the <body>
element is disabled when an offcanvas and its backdrop are visible. Use the scroll
option to toggle <body>
scrolling and the backdrop
option to toggle the use of a backdrop.
When backdrop
option is set to static
, the offcanvas will not close when clicking outside it.
Offcanvas with backdrop
Offcanvas with body scrolling
Offcanvas backdrop and scroll
Offcanvas static backdrop
<!-- Toggle buttons -->
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasBack" data-cfw-offcanvas-backdrop="true" data-cfw-offcanvas-scroll="false">Enable backdrop (default)</button>
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasScroll" data-cfw-offcanvas-backdrop="false" data-cfw-offcanvas-scroll="true">Disabled backdrop and enable scrolling</button>
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasBackScroll" data-cfw-offcanvas-backdrop="true" data-cfw-offcanvas-scroll="true">Enable both backdrop and scrolling</button>
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasStatic" data-cfw-offcanvas-backdrop="static">Static backdrop</button>
<!-- Offcanvas elements -->
<div id="offcanvasBack" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas with backdrop</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Body scrolling is disabled and you may click on the backdrop to dimiss the offcanvas item.
</div>
</div>
<div id="offcanvasScroll" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas with body scrolling</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
The backdrop has been disabled and the page can be scrolled and interacted with.
</div>
</div>
<div id="offcanvasBackScroll" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas backdrop and scroll</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Scrolling is enabled so you can scroll and interact with the page, but clicking on the backdrop will dismiss the offcanvas item.
</div>
</div>
<div id="offcanvasStatic" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Offcanvas static backdrop</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Clicking on a 'static' backdrop will not dismiss the offcanvas item.
</div>
</div>
Within a Navbar
Offcanvas is supported within the navbar component allowing for flexible navigation options along with support for responsive layouts.
Information and examples can be found in the Offcanvas section on the Navbar component page.
Contained Offcanvas
Contained offcanvas will display the backdrop and offcanvas within a specified element and not cover the entire page.
Place the offcanvas HTML within the container, apply position: relative;
to the container, and specify the rootElement
option on the trigger button to limit the offcanvas to the container.
It may also be useful to add a z-index
to the container, this will keep the offcanvas from appearing above other items that exist outside the container, such as a navbar. In the example below a z-index: 1;
has been added to the #offcanvasRootElement
container so that the contained offcanvas, and backdrop, do not overlap the site header when the page is scrolled.
Contained offcanvas
<div id="offcanvasRootElement" class="bg-light border overflow-hidden position-relative" style="height: 200px; z-index: 1;">
<div id="offcanvasContained" class="offcanvas offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Contained offcanvas</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Offcanvas content
</div>
<div class="offcanvas-footer">
Offcanvas footer
</div>
</div>
</div>
<button class="btn btn-primary" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasContained" data-cfw-offcanvas-root-element="#offcanvasRootElement">
Contained offcanvas
</button>
Responsive
Responsive offcanvas classes hide content outside the viewport from a specified breakpoint and down. Above that breakpoint, the contents within will behave as usual. For example, .offcanvas-lg
hides content in an offcanvas below the lg
breakpoint, but shows the content above the lg
breakpoint. Classes are available in the form of .offcanvas{-breakpoint}
.
Note the added case that target selectors are requred when using a dismiss control within a responsive offcanvas. In the following examples, the data-cfw-offcanvas-target
attribute is set for the data-cfw-dismiss="offcanvas"
controls.
Responsive offcanvas
This is content within an .offcanvas-lg
.
<button class="btn btn-primary d-lg-none" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasResponsive">Toggle offcanvas</button>
<div class="offcanvas-lg offcanvas-end" id="offcanvasResponsive">
<div class="offcanvas-header">
<h45 class="offcanvas-title h5">Responsive offcanvas</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" data-cfw-offcanvas-target="#offcanvasResponsive" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
<p class="mb-0">This is content within an <code>.offcanvas-lg</code>.</p>
</div>
</div>
Creating a responsive, contained offcanvas is also possible.
Responsive Contained offcanvas
<div id="offcanvasRootElementResponsive" class="bg-light border overflow-hidden position-relative" style="height: 200px; z-index: 1;">
<button class="btn btn-primary d-lg-none" type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#offcanvasContainedResponsive" data-cfw-offcanvas-root-element="#offcanvasRootElementResponsive">
Responsive Contained offcanvas
</button>
<div id="offcanvasContainedResponsive" class="offcanvas-lg offcanvas-start">
<div class="offcanvas-header">
<h4 class="offcanvas-title h5">Responsive Contained offcanvas</h4>
<button type="button" class="close" data-cfw-dismiss="offcanvas" data-cfw-offcanvas-target="#offcanvasContainedResponsive" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="offcanvas-body">
Responsive contained offcanvas content
</div>
</div>
</div>
Usage
The offcanvas widget toggles your hidden content on demand, via data attributes or JavaScript. It also generates a .offcanvas-backdrop
to provide a click area for dismissing shown offcanvas when clicking outside the offcanvas.
Via Data Attributes
Toggle
Activate an offcanvas without writing JavaScript. Set data-cfw="offcanvas"
on a controller element, like a button, along with a data-cfw-offcanvas-target="#foo"
or href="#foo"
to target a specific offcanvas to toggle.
<button type="button" data-cfw="offcanvas" data-cfw-offcanvas-target="#myOffcanvas">Launch offcanvas</button>
Dismiss
Dismissal can be achieved with data-cfw-dismiss
attributes on a button within the offcanvas as demonstrated below:
<button type="button" class="close" data-cfw-dismiss="offcanvas" aria-label="Close"><span aria-hidden="true">×</span></button>
or on a button outside the offcanvas using the additional data-cfw-offcanvas-target
as demonstrated below:
<button type="button" class="close" data-cfw-dismiss="offcanvas" data-cfw-offcanvas-target="#myOffcanvas">Close offcanvas</button>
While both ways to dismiss an offcanvas are supported, keep in mind that dismissing from outside an offcanvas does not match ARIA Authoring Practices Guide dialog (modal) pattern. Do this at your own risk.
Via JavaScript
Call an offcanvas with id myOffcanvas
with a single line of JavaScript:
$('#myOffcanvas').CFW_Offcanvas();
Close Triggers
Any an element with a data attribute of data-cfw-dismiss="offcanvas"
within the offcanvas element will act as a close trigger for the offcanvas. There can be multiple close triggers, such as a header/titlebar close and a cancel button in the footer.
With Positioned Content
Since the scrollbar is removed from the <body>
when an offcanvas is shown, there can be some shifting of content in fixed or sticky positioned elements.
The scrollbar handler will attempt to adjust padding values, and margin for sticky elements, to mitigate the content shift. These values will then be reset when the offcanvas dialog is closed.
Some positioning utility classes (.fixed-top
, .fixed-bottom
, .sticky-top
, and .sticky-bottom
) are automatically handled. For respsonsive or custom positioned items, there additional .is-fixed
and .is-sticky
helper classes can be added to an element to trigger the scrollbar handler to adjust for the shift. The scrollbar handler will check the computed style on any item with these classes, and only adjust when neccessary.
Custom positioned elements using translation to modify their position may not be handled correctly, so a custom solution may be needed.
Options
Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-cfw-offcanvas-
, as in data-cfw-offcanvas-animate=false
.
Name | Type | Default | Description |
---|---|---|---|
target |
string | null |
The selector of the target offcanvas. |
rootElement |
string | 'body' |
The selector of the container to display offcanvas within. |
animate |
boolean | true |
If offcanvas targets should fade and slide in. |
backdrop |
boolean | true |
Include an offcanvas-backdrop element. The backdrop is the semi-opaque overlay used to visually separate the offcanvas from the page content. |
scroll |
boolean | false |
Allow rootElement scrolling while offcanvas is open. |
keyboard |
boolean | true |
Closes the offcanvas when escape key is pressed. |
focus |
boolean | true |
Enforce focus when using keyboard navigation to remain within the offcanvas dialog. |
manual |
boolean | false |
If the offcanvas should be triggered manually through method calls, not from clicking the trigger element. Closing a manual offcanvas will not automatically return focus to the trigger item when the offcanvas is hidden. |
$('#myOffcanvas').CFW_Offcanvas({
animate: false
});
Methods
Method calls can be made on either the trigger or the target <div class="offcanvas">
element.
Method Name | Description |
---|---|
toggle |
Toggles an offcanvas dialog to be shown or hidden. |
show |
Shows an offcanvas dialog. |
hide |
Hides an offcanvas dialog. |
dispose |
Removes the event listeners from the trigger and target items. |
$('#myOffcanvas').CFW_Offcanvas('show');
Events
Event callbacks happen on the toggle/trigger element.
Event Type | Description |
---|---|
init.cfw.offcanvas |
This event fires after the offcanvas item is initialized. |
beforeShow.cfw.offcanvas |
This event is fired immediately when the show method is called. |
afterShow.cfw.offcanvas |
This event is fired when an offcanvas dialog has been made visible to the user (will wait for CSS transitions to complete). |
beforeHide.cfw.offcanvas |
This event is fired immediately when the hide method is called. |
afterHide.cfw.offcanvas |
This event is fired when an offcanvas dialog has been hidden from the user (will wait for CSS transitions to complete). |
$('#myOffcanvas').on('afterHide.cfw.offcanvas', function() {
// do something...
});
Accessibility
Offcanvas Title
It is recommended that a .offcanvas-title
item is used, even if visually hidden, within the offcanvas since it will be automatically be found and linked with an aria-labelledby
on the .offcanvas
container. This provides a potential description of the offcanvas to screen-reader users when the offcanvas is shown and focus is automatically moved to the .offcanvas
container.
Key Commands
The following key commands are handled when focus is inside the offcanvas:
- Esc - Close the offcanvas
- Tab - Moves focus to next focusable element inside the dialog. When focus is on the last focusable element in the dialog, moves focus to the first focusable element in the dialog.
- Shift + Tab - Moves focus to previous focusable element inside the dialog. When focus is on the first focusable element in the dialog, moves focus to the last focusable element in the dialog.
Enforced Focus
Offcanvas employ a 'focus trap' in an attempt to keep focus with the offcanvas dialog when one is open, as specified by the WAI-ARIA recommendations.
If for some reason you need to disable the enforced focus for offcanvas, you can override the behavior by setting the focus
option to false
.
SASS Reference
Variables
The available Customization options, or Sass variables, that can be customized for the offcanvas component.
Name | Type | Default | Description |
---|---|---|---|
$enable-offcanvas |
boolean | true |
Enable the generation of the offcanvas component classes.
Smaller segements of the offcanvas component classes can be disabled with the following $enable-* variables.
|
$enable-offcanvas-side-start |
boolean | true |
Enable the generation of the start side aligned offcanvas variant. |
$enable-offcanvas-side-end |
boolean | true |
Enable the generation of the end side aligned offcanvas variant. |
$enable-offcanvas-side-top |
boolean | true |
Enable the generation of the top side aligned offcanvas variant. |
$enable-offcanvas-side-bottom |
boolean | true |
Enable the generation of the bottom side aligned offcanvas variant. |
$enable-offcanvas-header |
boolean | true |
Enable the generation of the offcanvas header class. |
$enable-offcanvas-title |
boolean | true |
Enable the generation of the offcanvas title class. |
$enable-offcanvas-body |
boolean | true |
Enable the generation of the offcanvas body class. |
$enable-offcanvas-footer |
boolean | true |
Enable the generation of the offcanvas footer class. |
$enable-offcanvas-responsive |
boolean | true |
Enable the generation of the responsive offcanvas variants. |
$offcanvas-font-size |
string | $font-size-base |
Font size for offcanvas container. |
$offcanvas-bg |
string | $component-bg |
Background color for offcanvas container. |
$offcanvas-bg |
string | $component-bg |
Background color for offcanvas container. |
$offcanvas-color |
string | null |
Text color for offcanvas container. |
$offcanvas-border-color |
string | $component-overlay-border-color |
Border color for offcanvas container. |
$offcanvas-border-width |
string | $border-width |
Border width for offcanvas container. |
$offcanvas-box-shadow |
string | map-get($shadows, "d3") |
Border width for offcanvas container. |
$offcanvas-backdrop-bg |
string | $dark |
Background color for offcanvas backdrop. |
$offcanvas-backdrop-opacity |
string | .5 |
Opacity for offcanvas backdrop. |
$offcanvas-header-padding-y |
string | .75rem |
Vertical padding for offcanvas header. |
$offcanvas-header-padding-x |
string | 1rem |
Horizontal padding for offcanvas header. |
$offcanvas-header-color |
string | null |
Text color for offcanvas header. |
$offcanvas-header-background-color |
string | null |
Background color for offcanvas header. |
$offcanvas-header-border-color |
string | rgba($uibase-900, .2) |
Border color for offcanvas header. |
$offcanvas-header-border-width |
string | 0 |
Border width for offcanvas header. |
$offcanvas-title-line-height |
string | $line-height-base |
Line height for offcanvas header. |
$offcanvas-close-padding-y |
string | .75rem |
Vertical padding for close button in offcanvas header. |
$offcanvas-close-padding-x |
string | .75rem |
Horizontal padding for close button in offcanvas header. |
$offcanvas-body-padding-y |
string | .75rem |
Vertical padding for offcanvas body. |
$offcanvas-body-padding-x |
string | 1rem |
Horizontal padding for offcanvas body. |
$offcanvas-footer-padding-y |
string | .75rem |
Vertical padding for offcanvas footer. |
$offcanvas-footer-padding-x |
string | 1rem |
Horizontal padding for offcanvas footer. |
$offcanvas-footer-color |
string | null |
Text color for offcanvas footer. |
$offcanvas-footer-background-color |
string | null |
Background color for offcanvas footer. |
$offcanvas-footer-border-color |
string | $offcanvas-header-border-color |
Border color for offcanvas footer. |
$offcanvas-footer-border-width |
string | $offcanvas-header-border-width |
Border width for offcanvas footer. |
$offcanvas-horizontal-width |
string | rem(400px) |
Width for horizontal side aligned offcanvas containers. |
$offcanvas-vertical-height |
string | 33vh |
Height for vertical side aligned offcanvas containers. |
$offcanvas-transition |
string | transform .3s linear |
Transition settings for the .offcanvas animations.
|
$offcanvas-blocked-transition |
string | transform .15s linear |
Transition setting for close being blocked. |
$offcanvas-blocked-transform |
string | scale(1.01) |
Transform setting for close being blocked. |
$offcanvas-breakpoints |
list | map-keys($grid-breakpoints) |
Breakpoint list for responsive offcanvas variants. |
Mixins
No mixins available.