Toggle menu visibility with a hamburger button

by akogch

HTML

<div class="page">
  <button class="hamburger">
    <div class="line"></div>
    <div class="line"></div>
    <div class="line"></div>
  </button>
  <div class="menu">
    <div class="item">One</div>
    <div class="item">Two</div>
    <div class="item">Three</div>
  </div>
</div>

CSS

* {
  font-family: sans-serif;
}

.page {
  display: flex;
}

.hamburger {
  background-color: #222;
  width: 100px;
  height: 100px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}
.hamburger .line {
  width: 70px;
  height: 10px;
  margin-left: 10px;
  background-color: #fff;
  pointer-events: none;
}
.hamburger .line:not(:last-child) {
  margin-bottom: 10px;
}

.menu {
  display: none;
  background-color: #222;
  color: #fff;
  padding: 5px 0;
}
.menu .item {
  padding: 5px 15px;
  cursor: pointer;
}
.menu.active {
  display: inline-block;
}

JavaScript

let hamburger = document.querySelector('.hamburger');
let menu = document.querySelector('.menu');

const toggleMenu = () => {
  menu.classList.toggle('active');
}

hamburger.addEventListener('click', e => {
  e.stopPropagation();

  toggleMenu();
});

document.addEventListener('click', e => {
  let target = e.target;
  let its_menu = target == menu || menu.contains(target);
  let its_hamburger = target == hamburger;
  let menu_is_active = menu.classList.contains('active');
  
  if (!its_menu && !its_hamburger && menu_is_active) {
    toggleMenu();
  }
})