revy
revy

Reputation: 4707

CSS transition: chained transforms start simultaneously

Trying to build an hamburger button with animation using css transitions/transforms. I would like the rotation to start only after the translation of the first and the third span is completed (they should overlap with the middle span). Thus I put the transforms chained in the css like so:

transform: translate(0, -28px) rotate(-45deg);

but it seems not working, rotation starts together with translation. Anyone knows how to fix?

$( window ).load(function() {
  
  $("#hamburger").click(function(){
    $(this).toggleClass("open");
  });
  
});
*, *:before, *:after {
  box-sizing: border-box;
}

body {
  background-color: #333;
}

#hamburger {
  margin: 2em;
  position: relative;
  width: 80px;
  height: 60px;
  cursor: pointer;
}

#hamburger span {
  display: block;
  position: absolute;
  left: 0;
  width: 100%;
  height: 4px;
  background: #fff;
  
  -webkit-transition: transform .25s linear;
  -moz-transition: transform .25s linear;
  -o-transition: transform .25s linear;
  transition: transform .25s linear;
  
  &:nth-child(2) {
    -webkit-transition: width 0s linear .25s;
    -moz-transition: width 0s linear .25s;
    -o-transition: width 0s linear .25s;
    transition: width 0s linear .25s;
  }
}

#hamburger span:nth-child(1) {
  top: 0;
}

#hamburger span:nth-child(2) {
  top: 28px;
}

#hamburger span:nth-child(3) {
  bottom: 0;
}

#hamburger.open span:nth-child(1) {
  -webkit-transform: translate(0, 28px) rotate(45deg);
  -moz-transform: translate(0, 28px) rotate(45deg);
  -o-transform: translate(0, 28px) rotate(45deg);
  transform: translate(0, 28px) rotate(45deg);
}

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

#hamburger.open span:nth-child(3) {
  -webkit-transform: translate(0, -28px) rotate(-45deg);
  -moz-transform: translate(0, -28px) rotate(-45deg);
  -o-transform: translate(0, -28px) rotate(-45deg);
  transform: translate(0, -28px) rotate(-45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

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

Upvotes: 0

Views: 352

Answers (2)

revy
revy

Reputation: 4707

Solved following @Kadin Zhang suggestion splitting the animation in two transitions. I've substituted the translate transform with a simple change in the top property because in this way the transform-origin moves with the element (otherwise the origin remains in the previous coordinate system and the rotation will be wrong).

$( window ).load(function() {
  
  var state = false;
  
  $("#hamburger").click(function(){
    self = $(this);
    if (!state) {
      self.addClass("open-translate");
      setTimeout(function() {
        self.addClass("open-rotate");
        state = true;
      }, 250);
    }
    else {
      self.removeClass("open-rotate");
      setTimeout(function() {
        self.removeClass("open-translate");
        state = false;
      }, 250);
    }    
  });
  
});
*, *:before, *:after {
  box-sizing: border-box;
}

body {
  background-color: #333;
}

#hamburger {
  margin: 2em;
  position: relative;
  width: 80px;
  height: 60px;
  cursor: pointer;
}

#hamburger span {
  display: block;
  position: absolute;
  left: 0;
  width: 100%;
  height: 4px;
  background: #fff;
  
  -webkit-transition: all .25s linear;
  -moz-transition: all .25s linear;
  -o-transition: all .25s linear;
  transition: all .25s linear;
  
  &:nth-child(2) {
    -webkit-transition: width 0s linear .25s;
    -moz-transition: width 0s linear .25s;
    -o-transition: width 0s linear .25s;
    transition: width 0s linear .25s;
  }
}

#hamburger span:nth-child(1) {
  top: 0;
}

#hamburger span:nth-child(2) {
  top: 28px;
}

#hamburger span:nth-child(3) {
  top: 56px;
}

#hamburger.open-translate span:nth-child(1) {
  top: 28px;
}


#hamburger.open-rotate span:nth-child(1) {
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  transform: rotate(45deg);
}

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

#hamburger.open-translate span:nth-child(3) {
  top: 28px;
}

#hamburger.open-rotate span:nth-child(3) {
  -webkit-transform: rotate(-45deg);
  -moz-transform: rotate(-45deg);
  -o-transform: rotate(-45deg);
  transform: rotate(-45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

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

Upvotes: 0

user8887068
user8887068

Reputation:

You could split your transform into two different classes, one with translate() and one with rotate(), and then split up the transitions with .delay(), like so:

$("#hamburger").click(function(){
    $(this).toggleClass("translateClass");
    $(this).delay(250).toggleClass("rotateClass");
);

Upvotes: 4

Related Questions