1

I have a simple hamburger icon and I want to trigger CSS animation on click via pure javascript(no jquery please). I am doing this by adding and removing a class on hamburger icon when I add the class the CSS animation is happening however when I remove the class the animation is not happening, the hamburger line is coming back abruptly without animating. Basically I want the animation to reverse and come back to original position.

Here is the code:

var hamburgerMenu = document.querySelector('.hamburger-menu');
hamburgerMenu.addEventListener('click', function() {
  var hamburgerMenuSpan2 = document.querySelector('.hamburger-second');

  hamburgerMenuSpan2.classList.toggle('hamburger-line-2');
});
.hamburger-menu {
  position: absolute;
  top: 20px;
  right: 20px;
}

.hamburger-line-2 {
  animation-name: animate;
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
  animation-direction: alternate;
}

@keyframes animate {
  0% {
    width: 40px;
  }
  100% {
    width: 0px;
  }
}

.hamburger-menu span {
  display: block;
  width: 40px;
  height: 2px;
  background: black;
  margin: 10px 0px;
}
<div class="hamburger-menu">
  <span class="hamburger-line-1"></span>
  <span class="hamburger-second"></span>
  <span class="hamburger-line-3"></span>
</div>

Basically I want the hamburger icon line to become 0px width on click with duration and then whenever user clicks again I want the hamburger icon line to become original width starting from 0.

2 Answers 2

5

A bit ugly, because of the extra class needed, but it works:

var hamburgerMenu = document.querySelector('.hamburger-menu');
hamburgerMenu.addEventListener('click', function() {
  var hamburgerMenuSpan2 = document.querySelector('.hamburger-second');

  if (hamburgerMenuSpan2.classList.contains("animate-out")) {
    hamburgerMenuSpan2.classList.remove("animate-out");
    hamburgerMenuSpan2.classList.add("animate-in");
  } else {
    hamburgerMenuSpan2.classList.add("animate-out");
    hamburgerMenuSpan2.classList.remove("animate-in");
  }

});
.hamburger-menu {
  position: absolute;
  top: 20px;
  right: 20px;
}

.hamburger-line-2 {
  animation-duration: 3s;
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
  animation-direction: alternate;
}

.animate-out {
  animation-name: animate-out;
}

.animate-in {
  animation-name: animate-in;
}

@keyframes animate-out {
  0% {
    width: 40px;
  }
  100% {
    width: 0px;
  }
}

@keyframes animate-in {
  0% {
    width: 0px;
  }
  100% {
    width: 40px;
  }
}

.hamburger-menu span {
  display: block;
  width: 40px;
  height: 2px;
  background: black;
  margin: 10px 0px;
}
<div class="hamburger-menu">
  <span class="hamburger-line-1"></span>
  <span class="hamburger-second hamburger-line-2"></span>
  <span class="hamburger-line-3"></span>
</div>

Sign up to request clarification or add additional context in comments.

Comments

2

If you are free to use CSS transition, then this could be a great solution.

var hamburgerMenu = document.querySelector('.hamburger-menu');
hamburgerMenu.addEventListener('click', function() {
  var hamburgerMenuSpan2 = document.querySelector('.hamburger-second');

  if (hamburgerMenuSpan2.classList.contains('low-width')) {
    hamburgerMenuSpan2.classList.remove('low-width');
  } else {
    hamburgerMenuSpan2.classList.add('low-width');
  }
});
.hamburger-menu {
  position: absolute;
  top: 20px;
  right: 20px;
}

.hamburger-second {
  transition: width 3s ease-in-out;
}

.low-width {
  width: 0px !important;
}

.hamburger-menu span {
  display: block;
  width: 40px;
  height: 2px;
  background: black;
  margin: 10px 0px;
}
<div class="hamburger-menu">
  <span class="hamburger-line-1"></span>
  <span class="hamburger-second"></span>
  <span class="hamburger-line-3"></span>
</div>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.