SVG Menu Icon

This is a very simple ‘hamburger’ menu icon using SVG. It also has a simple CSS transition that modifies the icon to display as n ‘X’ icon, when toggled via JS.

Notes for improvements in the future:

  1. Perhaps this is better with HTML elements such as empty spans, instead of an SVG element.
  2. Perhaps use a button instead of an anchor element.
  3. Use CSS keyframe animations and improve the animation effect by moving .line-top and .line-bottom into the middle of the parent div, then rotating each one 45 degrees and -45 degrees respectively. The animation should look better.

CodePen

JavaScript

const overlayNavToggle = document.querySelector('.overlay-nav-toggle')

overlayNavToggle.addEventListener('click', () => {
  overlayNavToggle.classList.toggle('clicked')
})

HTML

<a class="overlay-nav-toggle" href="#" aria-label="Toggle Navigation Menu Overlay">
  <svg class="menu-hamburger" viewBox="0 0 45 30" xmlns="https://www.w3.org/2000/svg">
      <g>
          <line class="line-top" x1="0" x2="45" stroke="#000" stroke-width="3" />
          <line class="line-middle" x1="0" x2="45" stroke="#000" stroke-width="3" />
          <line class="line-bottom" x1="0" x2="45" stroke="#000" stroke-width="3" />
      </g>
  </svg>
</a>

CSS

:root {
  --menu-icon_width: 45px;
  --menu-icon_height: 45px;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: 100vh;
  margin: 0;
  background-color: azure;
}

.overlay-nav-toggle {
  display: block;
  width: var(--menu-icon_width);
  height: var(--menu-icon_height);
  margin-inline: auto;
}

.menu-hamburger {
  width: var(--menu-icon_width);
  height: var(--menu-icon_height);
  background-color: gainsboro; // background color is added so that you can see the parenet element in which the menu icon is contained within. this is intended to be removed in production.
  
  .line-top,
  .line-middle,
  .line-bottom {
    transition: all 0.5s;
    transform-origin: center center;
    stroke: rebeccapurple;
  }
  
  .line-top {
    transform: translateY(2px);
  }

  .line-middle {
    transform: translateY(15px);
  }

  .line-bottom {
    transform: translateY(28px);
  }
}

.overlay-nav-toggle.clicked {
  .menu-hamburger {
    .line-middle {
      opacity: 0;
    }
    
    .line-top {
      transform: rotate(45deg) translateY(15px);
    }
    
    .line-bottom {
      transform: rotate(-45deg) translateY(15px);
    }
  }
}

CodePen