MyLibary MyLibary - 6 months ago 11
Javascript Question

CSS3 transition & transform is not working well on class removal

I've made some nice hamburger effect which is pretty common these days over the websites in mobile navigation bar.

So when someone click the hamburger it turn the X perfectly (when adding a "open" class) but when the class removed the animation is changing weirdly, please watch the effect at the following code:

HTML:

<div id="hamburger">
<span></span>
<span></span>
<span></span>
</div>


CSS:

#hamburger {
float: left;
width: 20px;
height: 25px;
position: relative;
}

#hamburger span {
width: 100%;
height: 3px;
border-radius: 5px;
background: #000000;
position: absolute;
display: block;
-webkit-transform: rotate3d(0, 0, 1, 0deg);
-moz-transform: rotate3d(0, 0, 1, 0deg);
-o-transform: rotate3d(0, 0, 1, 0deg);
transform: rotate3d(0, 0, 1, 0deg);
}

#hamburger span:nth-child(1) {
top: 0;
-moz-transition: top 0.3s ease-in-out, -moz-transform 0.3s ease 0.3s;
-o-transition: top 0.3s ease-in-out, -o-transform 0.3s ease 0.3s;
-webkit-transition: top 0.3s ease-in-out, -webkit-transform 0.3s ease;
-webkit-transition-delay: 0s, 0.3s;
transition: top 0.3s ease-in-out, transform 0.3s ease 0.3s;
}

#hamburger span:nth-child(2) {
top: 7px;
opacity: 1;
-moz-transition: opacity 0.3s ease-in-out;
-o-transition: opacity 0.3s ease-in-out;
-webkit-transition: opacity 0.3s ease-in-out;
transition: opacity 0.3s ease-in-out;
}

#hamburger span:nth-child(3) {
top: 14px;
-moz-transition: top 0.3s ease-in-out, -moz-transform 0.3s ease 0.3s;
-o-transition: top 0.3s ease-in-out, -o-transform 0.3s ease 0.3s;
-webkit-transition: top 0.3s ease-in-out, -webkit-transform 0.3s ease;
-webkit-transition-delay: 0s, 0.3s;
transition: top 0.3s ease-in-out, transform 0.3s ease 0.3s;
}


#hamburger.open span:nth-child(1) {
top: 7px;
transform: rotate3d(0, 0, 1, 45deg);
}

#hamburger.open span:nth-child(2) {
opacity: 0;
}

#hamburger.open span:nth-child(3) {
top: 7px;
transform: rotate3d(0, 0, 1, -45deg);
}


Javascript:

$(document).ready(function () {
$('#hamburger').click(function () {
$(this).toggleClass('open');
});
});


https://jsfiddle.net/phhkL4bu/4/

Can you please help me out?

Answer

You can correct the removal animation by doing the following:

  • Set the forward transition's setting within the .open selector. When the .open class is added, the opacity of second child is transitioned for a duration of 0.3s without any delay. At the same time, the top position of the other 2 children is also being transitioned. Then after a 0.3s delay, the transform of the 1st and 3rd children is transitioned. This gives the effect of the top and the bottom bar moving down and then rotating.
  • Set its exact reverse as transition setting in the default selector. That is,make the transform on the 1st and 3rd child transition immediately with a 0.3s duration while the top of these two children and the opacity of the 2nd child are transitioned after a delay of 0.3s. This setting will apply when the element loses the .open class and so,will produce the reverse effect.

$(document).ready(function() {
  $('#hamburger').click(function() {
    $(this).toggleClass('open');
  });
});
#hamburger {
  float: left;
  width: 20px;
  height: 25px;
  position: relative;
}
#hamburger span {
  width: 100%;
  height: 3px;
  border-radius: 5px;
  background: #000000;
  position: absolute;
  display: block;
  transform: rotate3d(0, 0, 1, 0deg);
}
#hamburger span:nth-child(1) {
  top: 0;
  transition: top 0.3s ease-in-out 0.3s, transform 0.3s ease;
}
#hamburger span:nth-child(2) {
  top: 7px;
  opacity: 1;
  transition: opacity 0.3s ease-in-out 0.3s;
}
#hamburger span:nth-child(3) {
  top: 14px;
  transition: top 0.3s ease-in-out 0.3s, transform 0.3s ease;
}
#hamburger.open span:nth-child(1) {
  top: 7px;
  transform: rotate3d(0, 0, 1, 45deg);
  transition: top 0.3s ease-in-out, transform 0.3s ease 0.3s;
}
#hamburger.open span:nth-child(2) {
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
}
#hamburger.open span:nth-child(3) {
  top: 7px;
  transform: rotate3d(0, 0, 1, -45deg);
  transition: top 0.3s ease-in-out, transform 0.3s ease 0.3s;
}
<div id="hamburger">
  <span></span>
  <span></span>
  <span></span>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>