Frustrating CSS Animations

Posted in Engineering, Front-End, Web Design

I want to like CSS3 animations: they seem cleaner than relying on setTimeout() or setInterval()-based Javascript animations, generally run faster and are optimized by the browser, sometimes even hardware accelerated. If I want smooth animations in a mobile browser, CSS3 is pretty much the only way to go.

But it always feels like I’m “hacking” CSS; that is, I punch in a series of properties, and through some set of obscure CSS syntactic and resolution rules, I’m able to get something that approximates what I really want. It’s one of the reasons why backend engineers hate trying to understand the black box that is the CSS rule engine.

CSS animations don’t make this better.

A little background – CSS3 provides two main ways to animate your DOM elements:

  • Transitions – If a specified CSS field changes value, the animation engine will interpolate the values in between and produce a smooth animation from the start to finish values.
  • Animations – Basically multiple transitions, the ability to list multiple keyframes to transit between.

For simple animations (e.g., sliding a box, rotating an image, etc.), they work pretty well with their limited syntax and options. There have been plenty of interesting CSS3 animation demos, but most of them concentrate on showcasing one special effect or some small piece of desktop UI. The CSS rules are pretty straight-forward, and most just play around with rotations and 3D transforms anyway.

But for webapps, with dynamically-created DOM elements and various animations for a variety of actions, CSS is a complete pain to deal with:

  • The syntax no longer follows a strict key: value pairing, and CSS properties don’t seem to be properly mapped to Javascript objects. That means that instead of element.style.top = x, I’m stuck with something like element.style.webkitTransition = 'transform3D(' + x + ', ' + y + ', ' + z + ')'. Strings are much more annoying to debug given CSS’s silent failure habits.
  • It’s difficult to know what went wrong with a CSS animation. Again, because bad CSS syntax is silently dropped, it’s already hard to debug faulty CSS rules. Given the added complexity of CSS animation declarations, it’s very easy to get nothing with no indication of where the mistake was.
  • There are no events fired during animations, only at start and end. Hacking around it essentially means using setTimeout() in Javascript again, syncing it with the CSS animation onscreen.
  • Keyframes are apparently really hard to modify. It’s nice for fancy static demos, but not for a list with dynamically-created items.

Maybe I’m stepping beyond what CSS animations were designed for, and expecting a more scriptable syntax and malleability with the feature; I can understand limiting the number of properties for common cases and for browser makers to optimize for them. The lack of integration with the DOM interface, though – when a lot of application state, models, and interactions are coded and stored in Javascript – make them much more limited than they really should be.

  • Hi Allen,

    You’re correct that the keyframes event hack does use setTimeout() but only when the more performant requestAnimationFrame() is not available.

    As more vendors implement this function the work around will perform much better.

    I also feel your pain on your last point – whilst it is possible to dynamically create new animations, its not so easy to modify existing ones!