-1

I have a mobile menu animation that is triggered by adding some CSS classes via Javascript (simplified version in the live code snippet below).

The problem I have is although the menu animates in correctly, when I close it, it just disappears and doesn't fade out like I intended.

I've put notes in the JS about what the different stages do, but I can't seem to get it fade out like the CSS animation class says it should do?

Any help would be so amazing.

CodePen: https://codepen.io/emilychews/pen/bQOXVm

Thanks, Emily.

var mobileMenuButton = document.querySelector(".button")
var mobileMenu = document.querySelector(".menu")

// TOGGLE MOBILE MENU
var clicked = false

function toggleMobileMenu() {
  
  if (clicked === false) {
// removes the `display-none` class added below in the `else` part of the statement, so menu can be toggled more than once
    mobileMenu.classList.remove("display-none") 
    
// changes `display:none` from stylesheet to `display:flex`
    mobileMenu.classList.add("display")                
    
// removes inactive animation that is added below   
    mobileMenu.classList.remove("mobileMenuInactive")
    
// adds the menuActive animation that animates the menu in   
    mobileMenu.classList.add("mobileMenuActive")
    
// changes word on menu button
    mobileMenuButton.textContent = "Close"
    
    clicked = true

  } else {
    
    mobileMenu.classList.remove("mobileMenuActive")
    mobileMenu.classList.add("mobileMenuInactive")
    mobileMenuButton.textContent = "Menu"
    mobileMenu.classList.add("display-none")
    
    clicked = false
  }
}

mobileMenuButton.addEventListener("click", function() {
  toggleMobileMenu()
}, false)
body {
  margin: 0;
  padding: 0;
  display: flex;
  width: 100%;
  height: 100vh;
  justify-content: center;
  align-items: center;
}

.wrapper {
  display: flex;
  align-items: center;
}

.menu {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 150px;
  background: blue;
  right: 0;
  top: 6rem;
  padding: 10px 0px;
  z-index: 99;
  width: 20%;
  height: calc(100vh - 10rem);
  color: white
}

.button {
  margin: 0 0 0 3rem;
  cursor: pointer;
  padding: 10px 20px;
  background: gray;
  color: white;
}

/*add & remove `display` property*/
.menu.display {display: flex;}
.menu.display-none {display: none;}

/*animations*/
.menu.mobileMenuActive {
  animation: showMobileMenu .5s ease-in forwards;
 }

.menu.mobileMenuInactive {
  animation: removeMobileMenu .5s ease-out forwards;
 }

@keyframes showMobileMenu {
  0% {opacity: 0;}
  100% {opacity: 1;}
}

@keyframes removeMobileMenu {
  0% {opacity: 1;}
  100% {opacity: 0;}
}
<div class="wrapper">
  <div class="menu">Menu</div>
  <div class="button">Click Me</div>
</div>
pjk_ok
  • 618
  • 7
  • 35
  • 90
  • 1
    Seems like the element gets hidden before the animation to fade-out can complete. May have to tell it to wait for the animation to finish before changing it to display-none. – Tim Hunter Nov 30 '18 at 22:58
  • JS takes the shortest route to get to the end. In this case its ignoring the change in opacity as the display is being changed to none. – pmkro Nov 30 '18 at 23:03
  • Also [another SO question](https://stackoverflow.com/questions/26607330/css-display-none-and-opacity-animation-with-keyframes-not-working) with a good answer re: this topic – pmkro Nov 30 '18 at 23:08
  • Hi @TimHunter, yes I do understand what is happening, it's just I can't get a solution to work. – pjk_ok Dec 01 '18 at 16:06
  • Hi @pmkro, the other question / answer you pointed me to has nothing to do with my question. – pjk_ok Dec 01 '18 at 16:08

1 Answers1

0

You need to wait 500 millisecondes (the time of your animation) before passing the display to none :

setTimeout(function(){
  mobileMenu.classList.add("display-none");  
},500);
Nicolas J
  • 43
  • 1
  • 10
  • Hi, I edited your code on code pen : https://codepen.io/nicolasjaussaud/pen/dQaVJw, that seems to works for me – Nicolas J Dec 01 '18 at 18:26