Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS transition stutters after being applied to element with CSS animation

I'm building an AngularJS application that shows and hides an element by transitioning its opacity. The element is also being rotated by applying a CSS keyframe animation. The problem I'm having is the transition or animation stutters.

When the element has an opacity of 1 and the transition fades it out to 0 then the element appears to go back a few frames. This is better demonstrated in a GIF. You can see it jump back just before the opacity changes.

This is my CSS.

.square {
  width: 100px;
  height: 100px;
  margin: 50px;
  background: black;
}

.appear.ng-hide-add {
   -webkit-transition: opacity 300ms linear;
  opacity: 1;
}

.appear.ng-hide-add.ng-hide-add-active {
  opacity: 0;
}

.appear.ng-hide-remove {
  -webkit-transition: opacity 300ms linear;
  opacity: 0;
}

.appear.ng-hide-remove.ng-hide-remove-active {
  opacity: 1;
}

@-webkit-keyframes rotate {
  from {
    -webkit-transform: rotate(0deg);
  }

  to {
    -webkit-transform: rotate(360deg);
  }
}

.rotate {
  -webkit-animation: rotate 1.5s infinite linear;  
}

This is my HTML.

<div ng-app="app" ng-init="show = true">
  <p>Toggle the opacity of the square. Sometimes the rotation is interrupted when the opacity transitions from 1 to 0.</p>
  <button ng-click="show =!show">Toggle</button>
  <div class="square appear rotate" ng-show="show"></div>
</div>

You can play with the whole thing in this codepen. Hoping someone can point me in the right direction.

like image 786
Tate Johnson Avatar asked Sep 30 '22 11:09

Tate Johnson


2 Answers

Here's one more workaround just for the fun of it. Slightly less ugly than the first one I suggested. Change the box background color opacity: http://codepen.io/anon/pen/DpuEh

HTML:

<div ng-app="app" ng-init="show = true">
  <button ng-click="show = !show">Toggle</button>
  <div class="square appear rotate" ng-class="{'hidden': !show}"></div>
</div>

CSS:

.square {
  width: 100px;
  height: 100px;
  margin: 50px;
   -webkit-transition: background 300ms linear;
  background: black;
}

.square.hidden {
  background: rgba(0, 0, 0, 0);
}

I'm using rgba to set the background opacity. Just setting the background to white would also have worked in this simple case.

like image 76
Henrik N Avatar answered Oct 03 '22 01:10

Henrik N


This is evidently a WebKit bug. This is clearly not how the CSS should behave, and it does behave as expected in Firefox if you remove the vendor prefixes. You will notice that the animation resets when an additional animations/transitions are applied. This is similar to a known bug that was recently fixed in which multiple CSS transitions being applied at different times would cause a layout flash. I would recommend reporting the bug to the WebKit team so that it can be fixed.

like image 24
Alexander O'Mara Avatar answered Oct 03 '22 00:10

Alexander O'Mara