1

Once I start animating, on Chrome I get a ripple effect. My circle transform scales up. On Firefox, that exact same animation is ignored for some reason.

$("#animate").click(function() {
  $("#square").toggleClass("animate");
  $("#fab").toggleClass("ripple");
});
@keyframes ripple {
  from {
    transform: scale(0)
  }
  to {
    transform: scale(20)
  }
}
#square {
  position: relative;
  width: 300px;
  height: 300px;
  overflow: hidden;
  border: 1px solid red;
  transition: background 0.1s linear 0.6s, transform 1s;
  transform: rotate(0deg);
}
#fab {
  position: absolute;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #4FB5AB;
  top: 122px;
  right: 0;
  transform: scale(1);
  transition: transform 1s;
}
.ripple {
  animation: ripple 1s 0.5s;
  transform: scale(20) !important;
  /*Duration - delay */
  transition: transform 0s 1s !important;
}
.animate {
  transform: rotate(90deg) !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="square">
  <div id="fab"></div>
</div>
<br />
<button id="animate">animate</button>

CodePen Demo

Harry
  • 87,580
  • 25
  • 202
  • 214
realappie
  • 4,656
  • 2
  • 29
  • 38

1 Answers1

1

Before I start explaining the problem with your code, here is a word of caution - Do not use transitions and animations together. They generally end up causing problems like the one faced here.

When an animation is specified on an element, it will take complete control over the properties that are being animated unless there is a rule with !important setting. If !important setting is used then that rule takes precedence over the animation. (but unfortunately Chrome and Firefox seem to be handling this case differently).

As per W3C Spec:

CSS Animations affect computed property values. During the execution of an animation, the computed value for a property is controlled by the animation. This overrides the value specified in the normal styling system. Animations override all normal rules, but are overriden by !important rules.

emphasis is mine


In your code, there were two problems and they are as follows:

  • Within .ripple selector, you were specifying the transition-duration as 0s, which means, there is no transition at all and that the change of transform is an instant one. As explained in the W3C Spec, Firefox seems to be (correctly) giving the control to the rule with !important setting (that is, the transform and transition within .ripple selector) and so it transitions the state change immediately after the specified 1s delay+. Chrome lets animation take control and thus produces the effect you are looking for.
  • Firefox seems to animate the element quicker than Chrome does and so while a duration of 1s is enough for the animation in Chrome, FF needs it to be 2s to be slower and show the effect.

+ - You can further verify this by removing the !important settings on the rules. Once !important is removed, the animation would take control.

$("#animate").click(function() {
  $("#square").toggleClass("animate");
  $("#fab").toggleClass("ripple");
});
@keyframes ripple {
  from {
    transform: scale(0)
  }
  to {
    transform: scale(20)
  }
}
#square {
  position: relative;
  width: 300px;
  height: 300px;
  overflow: hidden;
  border: 1px solid red;
  transition: background 0.1s linear 0.6s, transform 1s;
  transform: rotate(0deg);
}
#fab {
  position: absolute;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #4FB5AB;
  top: 122px;
  right: 0;
  transform: scale(1);
  transition: transform 1s;
}
#fab.ripple {
  animation: ripple 2s 1s;
  transform: scale(20);
  /*Duration - delay */
  transition: transform 1s 1s;
}
#square.animate {
  transform: rotate(90deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="square">
  <div id="fab"></div>
</div>
<br />
<button id="animate">animate</button>

Finally, please do not use !important unless it is mandatory. Instead just make the selector more specific. In the snippet, I have made it more specific by using the #id.class format.

Community
  • 1
  • 1
Harry
  • 87,580
  • 25
  • 202
  • 214
  • Thanks a lot! Not only did you fix my problem but you only gave me a very detailed explanation on what was causing it. I also didn't know I could override css rules by making the selectors more specific, but now I do! – realappie Jan 25 '16 at 17:00
  • 1
    @5parc: You're welcome buddy. Glad to know that you found it useful :) Yes, the `!important` were the problematic ones (and Firefox is the browser which looks to have implemented it as per specs). – Harry Jan 25 '16 at 17:01
  • Sorry just making sure we are on the same page. But the "!important" lines were the ones causing the issue right? – realappie Jan 25 '16 at 17:02
  • @5parc: Yes, they were. – Harry Jan 25 '16 at 17:03