Off Canvas Sidebar+ Pattern

This pattern has two sidebars off screen. A menu to the left and a sidebar with more information to the right. Click the button for each reveals that sidebar and clicking it again moves it off screen.

In addition with either of the menu or sidebar open, clicking the opposite button will move the open content off screen and reveal the content that was clicked. Because of this we'll use Javascript for the click events.

The HTML

The html structure below is similar to the html in the panels pattern. The changes are due to the change in click events. Gone are the checkboxes and labels. In are standard links. Also removed is the button to show the main content, since we'll reveal the main content by closing the open menu or sidebar.

<header>
  <div class="container">
    <a class="btn btn-1">Menu</a>
    <img class="logo" src="images/logo.png" width="252" height="46" />
    <a class="btn btn-2">More</a>
  </div>
</header>

<div class="wrapper">
  <div class="inner">

    <nav>
      <ul id="nav">
        <li><a href="">Back to Post</a></li>
        <li><a href="sidebar-nav.html">Sidebar Nav</a></li>
        <li><a href="sidebar-nav-js.html">Sidebar Nav JS</a></li>
        <li class="current"><a href="sidebar+.html">Sidebar+</a></li>
        <li><a href="panels.html">Panels</a></li>
      </ul>
    </nav>

    <div class="container main-content">
      <div id="content"></div>
    </div>

    <div id="sidebar"></div>
  </div>
</div>

<section class="subfooter"></section>
<div id="footer"></div>
					

The Default CSS

The default css is exactly the same as it was for the panels pattern. Not a single thing is different.

The CSS to Toggle the Menu and Sidebar

The css here is nearly identical to that of the panels pattern. We now only have 2 buttons so there's one less button state to check.

Also we're now using Javascript instead of radio buttons, so instead of a css :checked state, we look for the addition of a .menu or .more class.

.inner.menu {
  margin-left: 0;
}

.inner.more {
  margin-left: -200%;	
}
					

The CSS in Media Queries

Like much of the css above, the media queries are near identical to the panels pattern. The only difference is again one less button state and looking for classes as opposed to a checked pseudo selector.

@media screen and (min-width: 48em) {
  .inner,
  .inner.menu {
    margin-left: 0%;
  }
	
  .inner.more {
    margin-left: -37%;
  }
}
					

The Javascript

The Javascript is similar to what's in the sidebar js pattern. Here we have 2 jQuery functions, one for each button. The function intercepts the click function of the link and either adds or removes the appropriate class depending on the current state.

A new wrinkle here is that as we add the class to show either the menu or the sidebar, we also remove the class on the other in case it's open.

$(document).ready(function() {
  $('a.btn-1').click(function() {
    if($(this).parents('header').siblings('.wrapper').find('.inner').hasClass('menu')){
      $(this).parents('header').siblings('.wrapper').find('.inner').removeClass('menu');
    } else {
      $(this).parents('header').siblings('.wrapper').find('.inner').addClass('menu');
      $(this).parents('header').siblings('.wrapper').find('.inner').removeClass('more');
    }
    return false;
  });

  $('a.btn-2').click(function() {
    if($(this).parents('header').siblings('.wrapper').find('.inner').hasClass('more')){
      $(this).parents('header').siblings('.wrapper').find('.inner').removeClass('more');
    } else {
      $(this).parents('header').siblings('.wrapper').find('.inner').addClass('more');
      $(this).parents('header').siblings('.wrapper').find('.inner').removeClass('menu');
    }
    return false;
  });
});