Animations: CSS versus JavaScript

Choose the right properties and elements to animate

Mercedes Scenna

Talking about animations in general

Once upon a time, animations were javascript’s field, and styling the CSS’ field. That was a long time ago, animation has become more a must-have than a nice-to-have within the last years, meaning there are now simpler ways to “get your objects to move”.

Animation is critical to communication and interaction, it makes the interface more natural and smoother, animation reinforces hierarchy, relationships, structure, and cause and effect.

As the world evolve, mobile design grew, animations became part of CSS3. Animations, interactions, transitions, are possible with CSS, so stylesheets became more complex.

By offloading interpretation of changes to the perceptual system, animation allows the user to continue thinking about the task domain, with no need to shift contexts to the interface domain. By elimintation sudden visual changes, aniamtion lessens the chance that the user is surprised

Scott E. Hudson and John T. Stasko (1993)

Nowadays, the two primary ways of animation are with CSS and JavaScript. The path you choose will depend on the needs of your project and the results you want to achieve, and it will also affect the time and effort.

You could narrow it down to:

  • CSS: for states that can be reached with Css through pseudo-classes. Animation of dropdowns, buttons, or even menus can be achieved with Css, even though you might need JS to control the states.

  • Javascript is most useful for significant control over the animation, one that need a timeline control for example, or a deeper interaction with users. In general, for complex animations, Javascript is your choice. 

different features about css and JS 

CSS animation is declarative, it doesn’t contain any logic. It doesn’t accept context from either the user nor the user’s interactions (except for a few pseudo-classes like :hover). Animations will always and only perform what its author declared in the stylesheet. It doesn’t take information that the user might give in an input, or anything that might change the environment. 

Animations will be independent from the element itself, you will make your declarations in the stylesheet, and then use the animation’s name property to add the required animation to an element.  Lets say that you want to have your content of your page appear while the user scrolls, you can perform the transitions of the elements with CSS, but you will need Javascript to access and control the “scrolling” state. Just like Animate CSS, all animations are purely done in css, you add the link as stylecheet and you can smooth transitions on your site. But as explained on their github repository, you can go one step forward with Javscript. 

What is it then about the CSS animations? They have a great performance, you avoid loading big scripts, and most importantly the cross-browser support through vendor prefixes.

What about Javascript? With the logic and scripts you can almost do whatever you want your element to do on your site. In comparison, it is far more complex than transitions with CSS, that’s why results also look more complex. With JS, you can animate by Frames, and manually determine the values of the properties of the elements that are being animated. 

Javascripts are very powerful, you can create great things. But you can also mess up really bad because of it. You need to be very clean and it will show on the results. Great examples can be checked in Codrops Tutorials.

The big issue with Javascript is the performance consistency. More tools are appearing to make it more efficient and clean. 
Web Animations API tries to solve this by specifying best practices in the form of element.animate(). There is a great article in HTML5 Rocks blog worth reading if you are interested.

As an example, you can see an animation published in Google Developers. One is done in CSS and the other one in JS. You can find a sample of each one underneath the code!

/* This is a simplified version without
 * vendor prefixes. With them included which 
 * you will need) things get far more verbose!
 */
.box {
  /* Choose the animation */
  animation-name: movingBox;
  /* The animation’s duration */
  animation-duration: 1300ms;
  /* The number of times we want
      the animation to run */
  animation-iteration-count: infinite;
  /* Causes the animation to reverse
      on every odd iteration */
  animation-direction: alternate;
}

@keyframes movingBox {
  0% {
    transform: translate(0, 0);
    opacity: 0.3;
  }
  25% {
    opacity: 0.9;
  }
  50% {
    transform: translate(100px, 100px);
    opacity: 0.2;
  }
  100% {
    transform: translate(30px, 30px);
    opacity: 0.8;
  }
}
function Box () {

  var animationStartTime = 0;
  var animationDuration = 500;
  var target = document.querySelector('.box');

  this.startAnimation = function() {
    animationStartTime = Date.now();
    requestAnimationFrame(update);
  };

  function update() {
    var currentTime = Date.now();
    var positionInAnimation = (currentTime - animationStartTime) / animationDuration;

    var xPosition = positionInAnimation * 100;
    var yPosition = positionInAnimation * 100;

    target.style.transform = 'translate(' + xPosition + 'px, ' + yPosition + 'px)';

    if (positionInAnimation <= 1)
      requestAnimationFrame(update);
  }
}

var box = new Box();
box.startAnimation();





 
 

There are dedicated frameworks for animations, which are very powerfull and avoid most of the performance issues. They have great documentation, especially helpful if you are just starting. Greensock’s TweenMax is highly recommended, as well its lightweight version from it called TweenLite.

Performance in animations

There are some properties that are cheaper to animate than others. There are some properties that affect the geometry of elements, so when you change for example the width of an element, all children elements will be affected and resize. Behind each transition there is a browser processing it in terms of: calculate the styles that apply to the elements, generate the geometry and position for each element (Layout), create the pixels for each element (Paint) and finally draw the layers out to screen (Composite Layers). 
The smoother the animation looks, the less work it has behind. And the properties that give less work to the site are the less invasive ones, the ones that only affect composing.

Following, you can see the process the browser every time it loads, and when, during this process, the css classes are rendered. The sooner they are rendered, the more work it will take to animate them.

For a full list of css classes you can check the Css Triggers

Odoo CMS - a big picture

width
height
margin
position
...

box-shadow
border-radius
background
outline
...

transform
Opacity

Talking about the particular differences and merits in performance between CSS and Javascript, long discussions can be found all around the web. A list of keypoints that might be helpful:

  • CSS-based animations are usually handled in a separated thread from other tasks like painting, layout, javascripts. This means that if some complex tasks are being resolved, CSS-based animations can potentially keep going without being interrupted. 
    As stated before, changes to opacity and transform can be handled separately in the composition thread, so its always better to stick with these properties for your animations. 

  • If any animation triggers paint, layout, or both, the “main thread” will be required to do work. This will work the same for both CSS- and JavaScript-based animations, and if the browser is busy processing “layout” or “paint” will likely set aside any work associated with CSS or JavaScript execution. 
    JQuery is not a synonymous to Javascript, it got a bad reputation basically because JQuery is widely known to be slow in terms of performance. But there are so many libraries, also called JS Frameworks, that have workarounds and improvements on the subject, and work so much faster: the previously named GreenSock, Velocity.js, Polymer Project, React.

About Mercedes Scenna

The sassy frontend skilled/ She does not only coding but also conceptualizing and drawing/ Traveling and photography is her passion.