CSS animation, toggle rotate on click

Daniel Kobe picture Daniel Kobe · Jun 29, 2015 · Viewed 62.3k times · Source

I am try to have the caret in the following rotate 180 degrees on click for my dropdown menu. In the solution Im trying to implement, it changes the class of the the caret to toggle-up or toggle-down on click. The first time I click on it rotates up, the second time it immediately goes back to its starting position and then rotates back up. I smell dirty code, whats the easiest way to add this toggle rotation animation. Thanks in advance for any help.
Heres my current css:

.toggle-up {
  animation-name: toggle-up;
  animation-delay: 0.25s;
  animation-duration: 0.75s;
  animation-fill-mode: forwards;
}
.toggle-down {
  animation-name: toggle-down;
  animation-delay: 0.25s;
  animation-duration: 0.75s;
  animation-fill-mode: forwards;
}

/*animations*/
@keyframes toggle-up {
  100% {
    transform: rotate(180deg);
  }
}
@keyframes toggle-down {
  100% {
    transform: rotate(180deg);
  }
}

enter image description here

Answer

Kevin F picture Kevin F · Jun 29, 2015

You don't really need a keyframe animation for something this simple. If you just add a class to your icon on click then remove it this will apply your rotation. Here is a working plunkr using font awesome and a simple rotation. This is just a simple example, you will want to make use of vendor prefixes and be aware that css transitions do not work in older browsers.

<div id="container">
    <i id="icon" class="fa fa-arrow-down"></i>
</div>

.fa-arrow-down{
  transform: rotate(0deg);
  transition: transform 1s linear;
}

.fa-arrow-down.open{
  transform: rotate(180deg);
  transition: transform 1s linear;
}

(function(document){
  var div = document.getElementById('container');
  var icon = document.getElementById('icon');
  var open = false;

  div.addEventListener('click', function(){
    if(open){
      icon.className = 'fa fa-arrow-down';  
    } else{
      icon.className = 'fa fa-arrow-down open';
    }

    open = !open;
  });
})(document);