Last week we put out the code challenge #7, to build an Avengers Off Canvas sidebar using any tool or technology.

You can check out awesome submissions in the comments under the post, also on Twitter using the hashtag #codechallenge and via the Scotch Slack channel #codechallenge. In this post, we shall be building out the sidebar using plain JavaScript and implement transition effects using CSS transitions.

Understanding the Challenge

Off Canvas sidebars are great for UI/UX. With the sidebar sliding in and out on toggle, there is enough room in the body to perfectly place content whilst keeping the navbar out of view.

The Base

HTML and CSS code was provided to build out the base of the challenge. The Sass variant of CSS is however used to introduce variables in CSS.

The HTML

The HTML markup consists of a parent div, a child nav element and the main body. The main body also consists of the body text as well as the toggle button for the menu.

<!-- CONTAINER -->
<div class="canvas">

  <!--   SIDE NAV  -->
  <nav class="side-nav">
    <ul class="has-text-centered">
      <h5 class="title is-7 has-text-white">The OGs!</h5>

      <li><a href="#">Thor</a></li>
      <li><a href="#">Iron Man</a></li>
      <li><a href="#">Spidey</a></li>
      <li><a href="#">Black Widow</a></li>
      <li><a href="#">Nick Fury</a></li>
      <li><a href="#">Capt. Sizzle Amizzle</a></li>
      <li><a href="#">Hawkeye</a></li>
      <li><a href="#">Hulk! Arrghh!!</a></li>
    </ul>
  </nav>

  <!--   BODY SECTION -->
  <main class="main-content">

    <!--     TOGGLE BUTTON -->
    <a href="#" class="toggle-button">
      <i class="fas fa-bars"></i>
      <i class="far fa-window-close"></i> 
    </a>


    <!--     BODY TEXT -->
    <h1 class="title">Welcome to the Avengers HQ</h1>
    <h3 class="subtitle">Checkout the badasses on the left!</h3>
    <p>PS: Use the button up top to summon them!</p>
    <p>PPS: Click the menu button to send them back!</p>

  </main>
</div>

The CSS

As earlier stated, the Sass CSS variant was also employed to style the page.

$side-nav-width: 230px;

body, .canvas, .main-content     {
  min-height: 100vh;
}

// the overall container
.canvas  {

}

// style the side navigation
.canvas .side-nav  {
  position: absolute;
  display: block;
  width: $side-nav-width;
  transform: translateX(-$side-nav-width);

  color: #E6E9F7;
  background-color: #253781;
  padding-top: 20px;
  min-height: 100%;

  a       {
    color: #EEE;
    display: block;
    padding: 5px 10px;
    font-size: 0.85em;
    text-transform: uppercase;
    letter-spacing: 2px;
  }

}

// main content and toggle button
.main-content   {
  padding: 50px;
}

.toggle-button  {
  font-size: 3em;
  color: #333;
}

No JavaScript code was included in the script.

The Technique

To solve this challenge in plain JavaScript we shall toggle the class-list of the parent canvas div to show and hide the sidebar. After implementing the toggle visibility function, we shall use CSS transitions to build out the transition effects of the navbar.

Toggle Sidebar

Implementing the toggle function is quite straight-forward. We fetch the DOM element representing the area in view using the class .canvas, as well as the button to trigger the toggle function .toggle-button.

let container    = document.querySelector('.canvas')
let toggleButton = document.querySelector('.toggle-button')

toggleButton.addEventListener('click', (e) => {
  e.preventDefault();
  container.classList.toggle('show-nav');  
});

We used an addEventListener() function to trigger a function on the click of .toggle-button.

e.preventDefault() stops the button or DOM element from carrying out any default actions when clicked, for instance, submit a form if it's a submit button.

So far we have implemented the toggle function when the toggle-button is clicked. However, we do not have the class being toggled, we create that in CSS with:

.canvas.show-nav   {
  transform: translateX($side-nav-width);
  .fa-window-close {
    display: block;
  }
  .fa-bars {
    display:none;
  }
}

Great! We now have our side-bar appear on the left. The .show-nav class uses the CSS transform property to move the canvas to the right to the extent of the sidebar's width.

While the sidebar is active, the display of the font-awesome icon to close the window is set to block whereas it's counterpart which opens the window is set to none.

How do we ensure only one icon is visible at a time? We set the default display of the close icon to none. This way, the icon doesn't display until the parent .canvas div receives it's .show-nav class.

.fa-window-close {
  display:none;
  margin:12px 0px;
}

Transition Effect

So far we have a working sidebar which is displayed on the click of a button and hidden on the click of another button. For user experience, we would like to make the navbar appearance during toggle better by using the CSS transition property on the .canvas element. Using CSS, we set the transition property with:

.canvas  {
  transition: .5s cubic-bezier(.91,.06,.47,1.05) transform;
}

This sets the time of the transition to half a second, the transition style is set using cubic-bezier for more flexibility and the property to apply the transition on is the transform property.

You can see the final product here

Conclusion

In this challenge, we built out an Off Canvas sidebar which displays and hides on the click of a button. Off Canvas sidebars are great for navigation and also performant as the technique involves the translation of the whole area either left or right during toggle. Feel free to leave your comments under this post and let's look forward to the next post. Happy coding!