You can use ng-animate with ng-class with the add and remove animations. I'm looking to make one animation in CSS3 but haven't found good examples with ng-class online. So I was wondering if people have good examples they want to share.
I am not sure what my final animation will look like, but for the purpose of this example let's say I just want to make the height of the div gradually increase when I add the class myclass
.
<div ng-class="{{myclass:scopeVar}}" ng-animate="?????"></div>
**CSS**
.myclass.ng-add{??}
.myclass.ng-add-active{??}
.myclass.ng-remove{??}
.myclass.ng-remove-active{??}
Animating an ng-class
addition or removal using CSS transition has 3 stages. The order of these stages are very important, I almost spent a day figuring out why a simple animation wasn't working due incorrect understanding of the order in which classes are added.
Stage 1:
classname-add
/classname-remove
class is added.
Unlike what someone might think, this is actually added before the class is added to/removed from the element.
This is the stage where we should add the transition
property 1 as well as initial state of our animation.
Stage 2:
classname
class is added or removed.
This is where you specify the eventual styles of the element. This class often has nothing to do with our animation. Remember that we are animating the addition/removal of this class. This class itself shouldn't even need to be aware that there is an animation taking place around it.
Stage 3:
classname-add-active
/classname-remove-active
class is added.
This is added after the class is added to/removed from the element.
This is the stage where we should specify the final state of our animation.
To see this in action, let's create a classic fade-in-out animation shown when an element's selected state changes (selected
class change using ng-class).
angular.module('demo', ['ngAnimate'])
.controller('demoCtrl', function($scope) {
$scope.selected = false;
$scope.selectToggle = function() {
$scope.selected = !$scope.selected;
};
});
.item {
width: 50px;
height: 50px;
background: grey;
}
.item.selected {
/* this is the actual change to the elment
* which has nothing to do with the animation
*/
background-color: dodgerblue;
}
.item.selected-add,
.item.selected-remove {
/* Here we specify the transition property and
* initial state of the animation, which is hidden
* state having 0 opacity
*/
opacity: 0;
transition: opacity 3s;
}
.item.selected-add-active,
.item.selected-remove-active {
/* Here we specify the final state of the animation,
* which is visible having 1 opacity
*/
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular-animate.js"></script>
<div ng-app="demo" ng-controller="demoCtrl">
<div class="item" ng-class="{selected:selected}"></div>
<br>
<br>
<button ng-click="selectToggle();">
{{selected? 'Unselect' : 'Select'}}
</button>
</div>
1 Why should I specify the transition in the first state, instead of just adding it to the class being toggled or a static selector on the element?, you ask.
Well to explain this, assume you need a one-directional animation, for example a fade-out animation when a fade-out
class is added.
If you add transition
property on the fade-out
class itself, the transition stays on the element even after the animation. Which means when your final state (fade-out-add-active) is removed, the element will slowly fade-in back, so we get a fade-out-fade-in which is not what we wanted.
Undesired result
Desired result
I've found a solution to this problem so I thought I'd share it.
http://jsfiddle.net/nicolasmoise/XaL9r/1/
What's nice about this one is that it only requires two CSS classes. You can directly insert the CSS3 transition
property into your base class. Unlike other ng-animate cases, I believe all the animations are done in CSS3 (no messing with the DOM like with animations with ng-include etc...).
I want to thank Ilan Frumer for the link to his answer. His solution was for animation with ng-show which is very similar but a little different from animations with ng-class. Hence why I decided to post my example.