Simple off-screen nav

by thirdender

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css">
<header>
  <span class="logo">Logo</span>
  <button type="button" class="nav-toggle">
    <i class="fas fa-bars"></i>
  </button>
  <nav>
    <ul>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
      <li>Menu item</li>
    </ul>
  </nav>
</header>
<button type="button" class="nav-toggle-close">
  <span class="sr-only"></span>
</button>

SCSS

body {
  background: #282727;
  color: #fafafa;
  margin: 0;
  transition: transform 0.3s ease;
  overflow-x: hidden;
  min-height: 100vh;
  &.nav-open {
    transform: translate(-20em);
  }
}

header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px;
  .logo {
    flex: 1;
  }
  button {
    background: none;
    border: 0;
    color: inherit;
  }
  nav {
    position: fixed;
    top: 0;
    left: 100%;
    height: 100%;
    width: 20em;
    background: #2c2c2c;
    border-left: 1px solid #343536;
    overflow: auto;
  }
}

.nav-toggle-close {
  position: fixed;
  top: 0;
  right: 100%;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  box-shadow: -10px 0 20px -10px black inset;
  border: 0;
  opacity: 0;
  outline: 0;
  transition-duration: 0.3s;
  transition-property: opacity, right;
  transition-timing-function: ease;
  transition-delay: 0s, 0.3s;
  body.nav-open & {
    transition-delay: 0s;
    right: 0;
    left: 0;
    opacity: 1;
  }
}

// Following class is already in CSS
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  border: 0;
}

JavaScript

var navOpen = false;
document.querySelector('.nav-toggle').addEventListener('click', function() {
  navOpen = !navOpen;
  document.body.className = navOpen ? 'nav-open' : '';
  if (navOpen) {
  	document.body.className = 'nav-open';
    document.querySelector('header nav').scrollTop = 0;
  } else {
  	document.body.className = '';  
  }
});
document.querySelector('.nav-toggle-close').addEventListener('click', function() {
  navOpen = false;
  document.body.className = '';
});