Adding Animation to AngularJS Applications with CSS3 keyframes Rules

← PrevNext →

Animations bring web pages to life. A limited amount of animation on a web page is necessary to help set focus on important areas of the page. It has other uses too. You do not have to write lengthy codes in JavaScript for animation. With CSS3, you can easily add animations to your web page. AngularJS supports CSS3 animations and here I’ll show you how to add animation to an AngularJS application with CSS3 @keyframes rules.

AngularJS provides animation to a selected list of directives such as ng-view, ng-repeat etc. The table below shows the list of directives that are animation aware, that is, these directives know how and when to react to a particular event.

Slider demo
Directives
Events

ngRepeat
enter, leave and move
ngView, ngInclude, ngSwitch, ngif
enter and leave
ngClass, ngShow, ngHide
add and remove

An event occurs when something happened that changes the state of the directives. It’s a default behavior. Any change in a directive triggers an event (listed above) that will create the animation in the CSS. It provides animation during (enter) an event and after (leave) the event. A couple of examples will explain this phenomenon better.

Before you add animation to your AngularJS pages, you need to include the “angular-animate.js” library to your HTM page that would provide the animation properties. Add the Google CDN in the <head> section of your markup.

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular-animate.js">

Next, add the module ngAnimate in the <script> section as a dependency.

<script>
    var app = angular.module('app', ['ngAnimate']);
</script>

ngRepeat Animation Example

It’s a very simple example where I have a list of data that I wish to show using ngRepeat. However, when you select or unselect values from the list, it will animatedly display or hide the values.

The Markup and CSS
<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular-animate.js"></script>

    <style>
        div {
            width:300px;
            height:20px;
        }
        .animate.ng-leave {  
            -webkit-animation:1.5s leave;
            -moz-animation:1.5s leave;
            -o-animation:1.5s leave;
            animation:1.5s leave;
            position:relative;
        }
        @keyframes leave {
            from { opacity:1; height:20px; left:0; }
            to  {opacity:0; height:0; left:-50px; }
        }
        @-webkit-keyframes leave {
            from { opacity:1; height:20px; left:0; }
            to  {opacity:0; height:0; left:-50px; }
        }

                 
        .animate.ng-enter {
            -webkit-animation:1.5s enter;
            -moz-animation:1.5s enter;
            -o-animation:1.5s enter;
            animation:1.5s enter;
            position:relative;
        }
        @keyframes enter {
            from { opacity:0; height:0; left:-50px; }
            to { opacity:1; height:20px; left:0; }
        }
        @-webkit-keyframes enter {
            from { opacity:0; height:0; left:-50px; }
            to { opacity:1; height:20px; left:0; }
        }
    </style>
</head>

<body>

    <div ng-app="app"
        ng-init="list=[
            { name:'Computer Architecture', price:65 }, 
            { name:'Advanced Composite Materials', price:45 }, 
            { name:'Stategies Unplugged', price:43 }, 
            { name:'Teaching Science', price:50 }, 
            { name:'Challenging Times', price:22 }]">

        <p><input type="text" ng-model="price" /></p>

        <!-- LOOP.-->
        <div class="animate" ng-repeat="books in list | filter:price | orderBy:'name'">

            <div> {{ books.name + ' - ' + (books.price | currency) }} </div>

        </div>
    </div>

</body>
<script>
    // CREATE APPLICATION MODULE.
    var app = angular.module('app', ['ngAnimate']);
</script>
</html>
Try it

In the <style> section, I have applied CSS @keyframes rules for animation on enter and leave events. Next, I have added the class animate to the element with ng-repeat directive. Now every time the user selects a value, it will filter the list based on the value. The remaining values in the list will animatedly slide and fade away (leave) towards the left. Similarly, it will return (enter) animatedly to its normal form.

See this demo

The @keyframes rules for events leave and enter has from and to properties, that is, the start and end point to slide. I have defined opacity property for fading effect. The animation time is 1.5 seconds for both leave and enter events. It is neither too quick nor too slow.

ngInclude Animation Example

This is another interesting example and this time I am applying animation to the ngInclude directive. It’s a slider. As you know using ngInclude you dynamically add external pages to your parent page. You can add a sliding (animation) effect when you change the pages by clicking a button.

First, create 3 HTML pages such as page1.htm, page2.htm and page3.htm.

The CSS
<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular-animate.js"></script>

    <style>
        .animate {
            width:100%;
            height:100%;
            overflow:hidden;
            position:relative;
        }
        .animate.ng-enter {
            -webkit-animation:1.5s enter;
            -moz-animation:1.5s enter;
            -o-animation:1.5s enter;
            animation:1.5s enter;
            position:relative;
        }
        .animate.ng-enter-active {
            left:0;
        }
        @keyframes enter {
            from { opacity:0; left:50%; }
            to { opacity:1; left:0; }
        }
        @-webkit-keyframes enter {
            from { opacity:0; left:50%; }
            to { opacity:1; left:0; }
        }


        .animate.ng-leave {  
            -webkit-animation:1.5s leave;
            -moz-animation:1.5s leave;
            -o-animation:1.5s leave;
            animation:1.5s leave;
            position:relative;
        }
        @keyframes leave {
            from { opacity:1; left:0; top:0; position:absolute; }
            to  {opacity:0; left:-70px; top:0; position:absolute; }
        }
        @-webkit-keyframes leave {
            from { opacity:1; left:0; top:0; position:absolute; }
            to  {opacity:0; left:-70px; top:0; position:absolute; }
        }
    </style>
</head>
The Markup
<body>
    <div ng-app="app" ng-controller="slideController" 
        style="width:400px;
        height:100px;
        border:solid 1px #CCC;
        position:absolute;">

        <div ng-include="page" class="animate"></div>
        <p><input type="button" value="Next Page" ng-click="shownext()" /></p>
    </div>
</body>
The Script
<script>
    // CREATE APPLICATION MODULE.

    var slider_app = angular.module('app', ['ngAnimate']);

    // THE CONTROLLER TO INCLUDE PAGES DYNAMICALLY.
    slider_app.controller('slideController', function ($scope) {
        $scope.count = 1;
        $scope.page = "page1.htm";
        $scope.shownext = function () {
            if ($scope.count < 3) {
                $scope.count += 1;
                $scope.page = "page" + $scope.count + ".htm";
            }
            else {
                $scope.count = 1;
                $scope.page = "page" + $scope.count + ".htm";
            }
        }
    });
</script>
</html>
Conclusion

CSS Animation in Angular is simple; however, you must use it judiciously. First, find the necessary areas that need animation and according you can apply them on the respective directives. I usually use animation to set focus on certain changes that occur very quickly on a web page and I want my users to know when it happened. It has other usages too.

That’s it. If you have any queries or suggestions, do not hesitate to ask, just leave your message below.

See this demo

← PreviousNext →