1

I am working creating a full screen navigation menu that slides down and bounces on entrance.

However, when clicking my menu toggle button again to close the full screen menu, it doesn't slide back up and just abruptly exits the screen.

I added transition: 2.5s to the nav.overlay property to see if that would rectify the issue, but unfortunately, I can't get the menu to slide off screen on exit.

Any tips on what I may be missing?

const menuToggle = document.querySelector('a.menu-toggle')
const navMenu = document.querySelector('nav.overlay')

document.addEventListener('click', function() {
  const clickEd = menuToggle.contains(event.target)

  if (clickEd) {
    navMenu.classList.toggle('bounce-in-top')
    menuToggle.classList.toggle('clicked')
  } else {
    navMenu.classList.remove('bounce-in-top')
    menuToggle.classList.remove('clicked')
  }
})
a.menu-toggle {
  position: fixed;
  top: 20px;
  left: 18px;
  z-index: 1000;
  max-width: 590px;
  height: 100%;
  transition: all 0.5s ease;
  cursor: pointer;
  transition-delay: 0.2s;
}

a.menu-toggle svg {
  width: 65px;
  transition: all 0.5s ease;
  /* transition-delay: 0.2s; */
}

a.menu-toggle.clicked svg {
  transform: rotate(45deg);
}

.bounce-in-top {
  -webkit-animation: bounce-in-top 1.1s both;
  animation: bounce-in-top 1.1s both;
}

@-webkit-keyframes bounce-in-top {
  0% {
    -webkit-transform: translateY(-90%);
    transform: translateY(-90%);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
    opacity: 1;
  }
  38% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
    opacity: 1;
  }
  55% {
    -webkit-transform: translateY(-65px);
    transform: translateY(-65px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  72% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
  81% {
    -webkit-transform: translateY(-28px);
    transform: translateY(-28px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  90% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
  95% {
    -webkit-transform: translateY(-8px);
    transform: translateY(-8px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
}

@-webkit-keyframes bounce-in-top {
  0% {
    -webkit-transform: translateY(-90%);
    transform: translateY(-90%);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
    opacity: 1;
  }
  38% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
    opacity: 1;
  }
  55% {
    -webkit-transform: translateY(-65px);
    transform: translateY(-65px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  72% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
  81% {
    -webkit-transform: translateY(-28px);
    transform: translateY(-28px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  90% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
  95% {
    -webkit-transform: translateY(-8px);
    transform: translateY(-8px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
}

@keyframes bounce-in-top {
  0% {
    -webkit-transform: translateY(-500px);
    transform: translateY(-500px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
    opacity: 0;
  }
  38% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
    opacity: 1;
  }
  55% {
    -webkit-transform: translateY(-65px);
    transform: translateY(-65px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  72% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
  81% {
    -webkit-transform: translateY(-28px);
    transform: translateY(-28px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  90% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
  95% {
    -webkit-transform: translateY(-8px);
    transform: translateY(-8px);
    -webkit-animation-timing-function: ease-in;
    animation-timing-function: ease-in;
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
  }
}

nav.overlay {
  transform: translateY(-100%);
  -webkit-transition: 2.5s;
  transition: 2.5s;
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: hidden;
  top: 0;
  left: 0;
  background: red;
}


/* Position the content inside the overlay */

.overlay-content {
  position: relative;
  top: 25%;
  width: 100%;
  text-align: center;
  margin-top: 30px;
}


/* The navigation links inside the overlay */

.overlay a {
  padding: 8px;
  text-decoration: none;
  font-size: 36px;
  color: #fff;
  display: block;
  transition: 0.3s;
}

.overlay a:hover,
.overlay a:focus {
  color: #000;
}
<nav class="overlay">
  <div class="overlay-content">
    <a href="#">About</a>
    <a href="#">Services</a>
    <a href="#">Clients</a>
    <a href="#">Contact</a>
  </div>
</nav>
<a class="menu-toggle">
  <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 122 92" enable-background="new 0 0 122 92" xml:space="preserve">
      <g>
          <g>
              <line fill="#3B51A2" stroke="#EE5383" stroke-width="6" stroke-miterlimit="10" x1="59.81" y1="3.43" x2="59.81" y2="89.25"/>
              <line fill="#3B51A2" stroke="#EE5383" stroke-width="6" stroke-miterlimit="10" x1="19.18" y1="45.64" x2="105.32" y2="45.64"/>
          </g>
          <g>
              <line fill="#3B51A2" stroke="#000000" stroke-width="6" stroke-miterlimit="10" x1="55.31" y1="0.75" x2="55.31" y2="86.57"/>
              <line fill="#3B51A2" stroke="#000000" stroke-width="6" stroke-miterlimit="10" x1="14.68" y1="42.97" x2="100.82" y2="42.97"/>
          </g>
      </g>
      </svg>
</a>

View my Codepen

showdev
  • 28,454
  • 37
  • 55
  • 73
jayciemota
  • 23
  • 3
  • 1
    Does these answer your question? [Can't use the same animation in reverse for class toggle](https://stackoverflow.com/questions/43575336/cant-use-the-same-animation-in-reverse-for-class-toggle) and [Possible to reverse a css animation on class removal?](https://stackoverflow.com/questions/18023859/possible-to-reverse-a-css-animation-on-class-removal/) – showdev Jul 05 '21 at 03:30

1 Answers1

0

you can anothoer class, for example is bounce-out-top, animation is opposite of the bounce-in-top.

document.addEventListener('click', function() {
  const clickEd = menuToggle.contains(event.target)

  if (clickEd) {
    navMenu.classList.remove('bounce-out-top')
    navMenu.classList.toggle('bounce-in-top')
    menuToggle.classList.toggle('clicked')
  } else {
    // first remove `out`, then add `in`
    navMenu.classList.remove('bounce-in-top');
    navMenu.classList.add('bounce-out-top');
    menuToggle.classList.remove('clicked')
  }
})
wenzi
  • 348
  • 2
  • 10
  • Thanks for the tip! I tried this but unfortunately I'm now running into an issue where the class for the exit animation is being added when I click the toggle again. However, if I I click anywhere outside of the toggle button the exit animation class gets added and is applied. Not sure why this is happening. – jayciemota Jul 06 '21 at 01:05