guar47
guar47

Reputation: 88

Why height animation with display: none are isn't working?

I try to figure out with css animation, but faced to this issue.

I did the height animation with @keyframes from 0px to size and it's working, but if I want to revert animation from size to 0px and add display: none to parent element it isn't working. So display trigger earlier than animation did?

Do you have some advice how to resolve task like that through css?

Code

$('.toggle-nav').click(function (e) {
  e.preventDefault();

  $('nav').toggleClass('active');
});
.toggle-nav {
  padding: 7px 12px;
  text-decoration: none;
  background: #fff;
}
nav li {
  background: #fff;
  color: #000;
  animation: slide-down-list-revert .3s linear 0s;
}
nav {
  display: none;
}
nav.active {
  display: block;
}
nav.active li {
  display: block;
  animation: slide-down-list .3s linear 0s;
}

@keyframes slide-down-list {
  from {
    height: 0;
  }
  to {
    height: 30px;
  }
}
@keyframes slide-down-list-revert {
  from {
    height: 30px;
  }
  to {
    height: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="toggle-nav" href="#">&#9776;</a>
<nav>
  <ul>
     <li><a>Item 1</a></li>
     <li><a>Item 2</a></li>
  </ul>
</nav>

Also my code is here: https://jsfiddle.net/guar47/w6o8a52b/11/

Upvotes: 0

Views: 67

Answers (2)

Tejasvi Karne
Tejasvi Karne

Reputation: 648

With the way you have written it, the element will be hidden before your animation even begins. If you want to revert the visible state of the nav li, you first need to complete the animation and then hide it. This can be done by adding an animationend event to the nav or nav li and handler can hide it as soon as the animationend is fired.

I've rewritten something to that effect. Note that I added another class to your CSS called revert which runs your slide-down-list-revert animation.

$('.toggle-nav').click(function (e) {
  e.preventDefault();
  var nav = $('nav');
  if(!nav.hasClass('active')){
    nav.toggleClass('active');
  }
  else{
    nav.addClass('revert');
  }
});

$('nav').on('animationend', function(){
  if ($(this).hasClass('revert')){
    $('nav').toggleClass('revert active');
  }
});
.toggle-nav {
  padding: 7px 12px;
  text-decoration: none;
  background: #fff;
}
nav li {
  background: #fff;
  color: #000;
  animation: slide-down-list-revert .3s linear 0s;
}
nav {
  display: none;
}
nav.active {
  display: block;
}
nav.active li {
  display: block;
  animation: slide-down-list .3s linear 0s;
}
nav.revert li{
  animation: slide-down-list-revert .3s linear 0s;
}

@keyframes slide-down-list {
  from {
    height: 0;
  }
  to {
    height: 30px;
  }
}
@keyframes slide-down-list-revert {
  from {
    height: 30px;
  }
  to {
    height: 0;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="toggle-nav" href="#">&#9776;</a>
<nav>
  <ul>
     <li><a>Item 1</a></li>
     <li><a>Item 2</a></li>
  </ul>
</nav>

Upvotes: 1

Sanjay J
Sanjay J

Reputation: 11

You just need to replace your code with below code:

$('.toggle-nav').click(function (e) {
  e.preventDefault();
  $('nav').slideToggle();
});

Then remove other CSS that you are using for animation.

Upvotes: 1

Related Questions