Animations: CSS vs JavaScript

Hugo Di Francesco - Apr 13 '18 - - Dev Community

When should you use JavaScript if you can use CSS?

This post was sparked by a question I answered on Quora:
Which is better to use, CSS or JS?

The web frontend is built with the triumvirate of HTML, CSS and JavaScript (see “Backend code, frontend code and how they interact” for more details): HTML says what things are, CSS how they look and JavaScript does all the things the other two can’t.

Seeing it from this light the answer to the question: “When should you use JavaScript when you can use CSS?” is never.

HTML, CSS and JavaScript do overlap especially since HTML5 and CSS3. Animations before CSS3 used to be the premise of the JavaScript and complex animation orchestration still is with libraries like GSAP, but nowadays we can also animate using the transition CSS rule.

This leads us to formulate some rules around using JavaScript in the browser:

  • if you can do something with CSS over JavaScript, do it

  • if you can do something with HTML over JavaScript, do it

Why?

There are a few reasons why you should try to leverage the browser’s CSS engine instead of hand-rolling animations, focused states and so on.

This stems from the principle of writing code that is as simple as possible, but not too simple. CSS and HTML’s declarative natures lends them to writing concise, robust and maintainable code. Since JavaScript can do so much and break so many different ways, the less of it you write, the less likely you are to run into issues.

1. Resilience

CSS and HTML try their hardest to self-remedy. They’re super robust: one broken CSS rule doesn’t crash your whole web-app, a missing tag might break your layout but except in extreme cases it won’t stop your site from loading.

One JavaScript syntax error or a missing null/undefined check on a field before using it (eg. myObj.something when myObj is null/undefined) will crash your whole app, forcing your user to refresh the whole thing and possibly losing some work in the process.

2. Optimisation

Since CSS is declarative there is a lot more scope for optimisation. The browser can sometimes use hardware acceleration to do CSS things.

It can also optimise things like not computing off-screen element’s styles or run their animations.

JavaScript doesn’t have access to these kinds of APIs out of the box.

3. Easy and costly to get wrong

Beyond the fact that JavaScript is less resilient than CSS, even relatively well-written JavaScript can do things like locking the UI or even crash the browser (especially low-end ones).

With CSS, non-CSS3 compliant browsers aka pretty-damn-old-browser-that-you-dont-use-any-more-but-your-users-mightwill just ignore the transition rule, so by default you have graceful degradation. In JavaScript you would have to detect that the user is running old or low-spec hardware, making it an opt-in to graceful degradation… I know which one I prefer.

4. Cost of JavaScript

A whole lot more sites need CSS more than they need JavaScript. That’s why despite “Best Practices” a lot of developers (a lot = “I’m guilty of this”), still load their styles in the head even though they load their scripts at the end of the body.

CSS is also quite cheap to interpret since it’s declarative, you can parallelise the creation of the in-memory representation of styles (since each selector in the CSS can be interpreted in parallel) and also defer calculation of the final styles until when the elements are painted.

JavaScript, since it’s a general purpose programming language… just like CSS has to be loaded, but it also has to be parsed and JIT-compiled as well as run. Which means for the same amount (in terms of size on disk) of CSS and JavaScript, JavaScript costs more to your users in terms of hardware time.

5. Cost of maintenance and added dependencies

Loading in a JavaScript animation library costs you in two ways:

  1. you’re adding a dependency with its own API, which means potentially more things to learn for anyone looking to maintain the code after you

  2. you’re loading a dependency, adding to your JavaScript load/parse/run startup cost

CSS animations and detecting DOM state using pseudo-classes costs you nothing both in terms of loading and not incurring a dependency since CSS and HTML are backed by web standards. It’s very likely any new developers will be familiar with CSS animations, and if they’re not, they should be.

Feel free to get in touch with me on Twitter @hugo__df.

Leave some ♥️ if you enjoyed this, and here are some posts you might be interested in:

Originally published at codewithhugo.com on January 21, 2018.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .