Search code examples
javascripthtmlcsswebkit

Animations for an HTML5 Hamburger menu


I've been trying to get a working hamburger menu that not only functions but "looks good", but I've had issues trying to translate the menu onto the page, rather than it just appearing

I've attempted using webkit tools, but can't figure out how to get it to animate only once, and with the bar animations

Menu.style.display = "none";

function ShowHide(x) {
  x.classList.toggle("change");
  var Menu = document.getElementById("Menu");
  if (Menu.style.display === "none") {
    Menu.style.display = "block";
  } else {
    Menu.style.display = "none";
  }
}
.container {
  display: inline-block;
  cursor: pointer;
}

.bar1,
.bar2,
.bar3 {
  width: 35px;
  height: 5px;
  background-color: #333;
  margin: 6px 0;
  transition: 0.4s;
}

.change .bar1 {
  -webkit-transform: rotate(-45deg) translate(-9px, 6px);
  transform: rotate(-45deg) translate(-9px, 6px);
}

.change .bar2 {
  opacity: 0;
}

.change .bar3 {
  -webkit-transform: rotate(45deg) translate(-8px, -8px);
  transform: rotate(45deg) translate(-8px, -8px);
}


}
body {
  background-color: rgb(209, 224, 224);
}
.Menu {
  width: 150px;
  background-color: rgb(208, 208, 225);
  display: none
}
<div class="container" onclick="ShowHide(this)">
  <div class="bar1"></div>
  <div class="bar2"></div>
  <div class="bar3"></div>
</div>

<div id="Menu" style="width: 150px; background-color: rgb(208, 208, 225); display: none;">
  <h2><a href="Homepage.html">Homepage</a></h2>
  <br>
  <h2><a href="Subpage1.html">Subpage 1</a></h2>
  <br>
  <h2><a href="Subpage2.html">Subpage 2</a></h2>
  <br>
  <h2><a href="Subpage3.html">Subpage 3</a></h2>
  <br>
  <h2><a href="Subpage4.html">Subpage 4</a></h2>
  <br>
  <h2><a href="Subpage5.html">Subpage 5</a></h2>
  <br>

</div>


Solution

  • To make the menu transition along with the menu icon, you can add this to your ShowHide() function. I used a new .menu-hidden class to address this so that you can toggle it without if conditions:

    HTML:

    <div id="Menu" class="menu-hidden">
    

    JS:

    function ShowHide(x) {
      x.classList.toggle("change");
      var Menu = document.getElementById("Menu");
      Menu.classList.toggle("menu-hidden");
    }
    

    Since you want the menu to translate onto the page, instead of setting its display: none you can hide it by translating it off the page first:

    .menu-hidden {
      transform: translateX(-999px);
    }
    

    Finally, let's add the smooth transition to your CSS (I've also corrected your selector from .Menu class to #Menu id and moved the style to CSS from inline HTML):

    #Menu{
      width: 150px;
      background-color: rgb(208, 208, 225);
      transition: 0.4s;
    }
    

    In addition, to completely separate your JS from the HTML, you can use an event listener instead of the onclick attribute (this last step is not mandatory):

    var x = document.querySelector(".container");
    
    x.addEventListener("click", ShowHide);
    
    function ShowHide() {
      this.classList.toggle("change");
      var Menu = document.getElementById("Menu");
      Menu.classList.toggle("menu-hidden");
    }
    

    Here's the full code:

    var x = document.querySelector(".container");
    
    x.addEventListener("click", ShowHide);
    
    function ShowHide() {
      this.classList.toggle("change");
      var Menu = document.getElementById("Menu");
      Menu.classList.toggle("menu-hidden");
    }
    .container {
      display: inline-block;
      cursor: pointer;
    }
    
    .bar1, .bar2, .bar3 {
      width: 35px;
      height: 5px;
      background-color: #333;
      margin: 6px 0;
      transition: 0.4s;
    }
    
    .change .bar1 {
      -webkit-transform: rotate(-45deg) translate(-9px, 6px);
      transform: rotate(-45deg) translate(-9px, 6px);
    }
    
    .change .bar2 {opacity: 0;}
    
    .change .bar3 {
      -webkit-transform: rotate(45deg) translate(-8px, -8px);
      transform: rotate(45deg) translate(-8px, -8px);
    }
     
    body {
      background-color: rgb(209, 224, 224);
    }
    
    #Menu{
      width: 150px; background-color: rgb(208, 208, 225);
      transition: 0.4s;
    }
    
    .menu-hidden {
      transform: translateX(-999px);
    }
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" type="text/css" href="IST101.css">
        <script src="hamburger.js" defer></script>
        <title>Web design test</title>
    
    </head>
    <body>
        <div class="container">
      <div class="bar1"></div>
      <div class="bar2"></div>
      <div class="bar3"></div>
    </div>
    
    <div id="Menu" class="menu-hidden">
      <h2><a href="Homepage.html">Homepage</a></h2>
      <br>
      <h2><a href="Subpage1.html">Subpage 1</a></h2>
      <br>
      <h2><a href="Subpage2.html">Subpage 2</a></h2>
      <br>
      <h2><a href="Subpage3.html">Subpage 3</a></h2>
      <br>
      <h2><a href="Subpage4.html">Subpage 4</a></h2>
      <br>
      <h2><a href="Subpage5.html">Subpage 5</a></h2>
      <br>  
    
    </div>
    </body>
    </html>