Off-canvas Sidebar in Bootstrap 4 with Optional Overlay, Offset and Transitions

Bootstrap version: 4.2.1

← Back to All Demos

Description and HTML Demo

Defaults:

  • Offset: false
  • Overlay: true
  • Width: 330px
<!-- Left -->
<div id="bs-canvas-left" class="bs-canvas bs-canvas-anim bs-canvas-left position-fixed bg-light h-100">
    
<!-- Right -->
<div id="bs-canvas-right" class="bs-canvas bs-canvas-anim bs-canvas-right position-fixed bg-light h-100">

Right sidebar custom width: 400px

<!-- Right -->
<div id="bs-canvas-right" class="bs-canvas bs-canvas-anim bs-canvas-right position-fixed bg-light h-100" data-width="400px">

Left off-canvas full width content

<!-- Left -->
<div id="bs-canvas-left" class="bs-canvas bs-canvas-anim bs-canvas-left position-fixed bg-light h-100" data-width="100%">

Right sidebar with content offset

<!-- Right -->
<div id="bs-canvas-right" class="bs-canvas bs-canvas-anim bs-canvas-right position-fixed bg-light h-100" data-offset="true">
  • Offset: false
  • Overlay: false
  • Width: 330px
<!-- Left -->
<div id="bs-canvas-left" class="bs-canvas bs-canvas-anim bs-canvas-left position-fixed bg-light h-100" data-overlay="false">
    
<!-- Right -->
<div id="bs-canvas-right" class="bs-canvas bs-canvas-anim bs-canvas-right position-fixed bg-light h-100" data-overlay="false">
  • Offset: true
  • Overlay: false
  • Width: 330px
<!-- Left -->
<div id="bs-canvas-left" class="bs-canvas bs-canvas-anim bs-canvas-left position-fixed bg-light h-100" data-offset="true" data-overlay="false">
    
<!-- Right -->
<div id="bs-canvas-right" class="bs-canvas bs-canvas-anim bs-canvas-right position-fixed bg-light h-100" data-offset="true" data-overlay="false">
HTML
<body>
    <!-- Overlay, must be placed direct after the opening body tag. -->
    <div class="bs-canvas-overlay bs-canvas-anim bg-dark position-fixed w-100 h-100"></div>
    
    <!-- Non-pushable content. -->
    <nav class="navbar">
        ...
    </nav>
    
    <!-- Pushable content along with off-canvas opener. -->
    <div class="bs-offset-main bs-canvas-anim">
        ...
        <button class="btn btn-danger" type="button" data-toggle="canvas" data-target="#bs-canvas-left" aria-expanded="false" aria-controls="bs-canvas-left">&#9776;</button>
        <button class="btn btn-primary" type="button" data-toggle="canvas" data-target="#bs-canvas-right" aria-expanded="false" aria-controls="bs-canvas-right">&#9776;</button>
        ...
        ...
    </div>
    
    <!-- Off-canvas sidebar markup, left/right or both. -->
    <div id="bs-canvas-left" class="bs-canvas bs-canvas-anim bs-canvas-left position-fixed bg-light h-100">
        <header class="bs-canvas-header p-3 bg-success">
            <h4 class="d-inline-block text-light mb-0">Canvas Header</h4>
            <button type="button" class="bs-canvas-close close" aria-label="Close"><span aria-hidden="true" class="text-light">&times;</span></button>
        </header>
        <div class="bs-canvas-content px-3 py-5">
            ...
        </div>
    </div>
        
    <div id="bs-canvas-right" class="bs-canvas bs-canvas-anim bs-canvas-right position-fixed bg-light h-100">
        <header class="bs-canvas-header p-3 bg-primary overflow-auto">
            <button type="button" class="bs-canvas-close float-left close" aria-label="Close"><span aria-hidden="true" class="text-light">&times;</span></button>
            <h4 class="d-inline-block text-light mb-0 float-right">Canvas Header</h4>
        </header>
        <div class="bs-canvas-content px-3 py-5">
            ...
        </div>    
    </div>
</body>
  • Remove the occurrences of bs-canvas-anim class from HTML to remove the smooth transition.
  • Skip the respective sidebar and the opener button markup if you don't need at a particular side.
  • Data attribute targeting to a class would fail to properly alter aria-expanded attribute value and further functioning.
  • While the full-width off-canvas sidebar for a menu is supported, you need to modify the sidebar markup to visually appear like a menu.
CSS
.bs-canvas-overlay {
   opacity: 0;
   z-index: -1;
}

.bs-canvas-overlay.show {
   opacity: 0.85;
   z-index: 1100;
}

.bs-canvas {
   top: 0;
   width: 0;
   z-index: 1110;
   overflow-x: hidden;
   overflow-y: auto;
}

.bs-canvas-left {
   left: 0;
}

.bs-canvas-right {
   right: 0;
}

.bs-canvas-anim {
   transition: all .4s ease-out;
   -webkit-transition: all .4s ease-out;
   -moz-transition: all .4s ease-out;
   -ms-transition: all .4s ease-out;
}
JS
jQuery(document).ready(function($) {
   var bsDefaults = {
         offset: false,
         overlay: true,
         width: '330px'
      },
      bsMain = $('.bs-offset-main'),
      bsOverlay = $('.bs-canvas-overlay');

   $('[data-toggle="canvas"][aria-expanded="false"]').on('click', function() {
      var canvas = $(this).data('target'),
         opts = $.extend({}, bsDefaults, $(canvas).data()),
         prop = $(canvas).hasClass('bs-canvas-right') ? 'margin-right' : 'margin-left';

      if (opts.width === '100%')
         opts.offset = false;
      
      $(canvas).css('width', opts.width);
      if (opts.offset && bsMain.length)
         bsMain.css(prop, opts.width);

      $(canvas + ' .bs-canvas-close').attr('aria-expanded', "true");
      $('[data-toggle="canvas"][data-target="' + canvas + '"]').attr('aria-expanded', "true");
      if (opts.overlay && bsOverlay.length)
         bsOverlay.addClass('show');
      return false;
   });

   $('.bs-canvas-close, .bs-canvas-overlay').on('click', function() {
      var canvas, aria;
      if ($(this).hasClass('bs-canvas-close')) {
         canvas = $(this).closest('.bs-canvas');
         aria = $(this).add($('[data-toggle="canvas"][data-target="#' + canvas.attr('id') + '"]'));
         if (bsMain.length)
            bsMain.css(($(canvas).hasClass('bs-canvas-right') ? 'margin-right' : 'margin-left'), '');
      } else {
         canvas = $('.bs-canvas');
         aria = $('.bs-canvas-close, [data-toggle="canvas"]');
         if (bsMain.length)
            bsMain.css({
               'margin-left': '',
               'margin-right': ''
            });
      }
      canvas.css('width', '');
      aria.attr('aria-expanded', "false");
      if (bsOverlay.length)
         bsOverlay.removeClass('show');
      return false;
   });
});

Canvas Header

Featured
Special title treatment

With supporting text below as a natural lead-in to additional content.

Go somewhere

Canvas Header

# Item Qty. Remove
1 Quilt 2 ×
2 Shawl 1 ×
3 Pillow 5 ×

Subscribe to our newsletter:

@