Friday, April 23, 2010

Note: This blog post did reflect my opinion at the time of writing. Since then technology has evolved and now this has become less of an issue. I will leave the post online, but if you came to learn about how to do animation today, reading will be a waste of your time.

A little more than a year ago Safari introduced experimental
support for CSS based animations, to compliment transformations and transitions. I have no gripe with transitions
and transformations, but I think animations belong in the DOM and not in CSS. My main argument is that animations will
most of the time be triggered by DOM-events, and during at least the next five years most CSS-based animations will be
duplicated using classic DOM-methods anyway. The purported separation of animation (for designers) who are supposedly
scared away from scripting is not a valid
argument, since they are going to use libraries anyway. (And, frankly, the CSS animation syntax in itself looks
quite scary to most people!)

Originally, this started out mostly as a gut
feeling, and the arguments that I've made on the W3C mailing list
are varied
and admittedly a bit confused.
I was thinking out loud more than I was presenting a coherent argument. Hopefully this blog
post will come across as more reasonable!

I also believe that this discussion needs to be known outside of the CSS working group and the participants on the www-style
mailing list. Specifically, it needs the input of developers of JavaScript libraries and normal web developers. These are
the people who will be affected the most by any decision. (I am providing an abundance of links to the discussion on the mailing
list for context.)

CSS animation – the good parts

A few aspects of the CSS animation proposal are brilliant and
not of dispute:

Declarative syntax. Designers specify what effect they want, not how the browser should achieve it.

Hardware acceleration. Animations get smoother, faster and less CPU-draining. The GPU is optimized for this
and can perform the calculations using only a fraction of the power and time a CPU would take to do the same number crunching.

When I am asking the CSS working group to reconsider CSS animations I am not in any way trying to take away these two strong points.
I am firmly pro having GPU-accelerated, declarative animations in the browser.
I just think the DOM is a better fit for them.

What will be animated?

CSS has no events, it has states. Basically it knows the focused and unfocused state on links and widgets and if a pointer
is hovering, clicking ("active") or not hovering over an element. While exeperimenting with the CSS animation syntax,
the working is producing examples using these states. Ironically mobile devices are one of the main reasons why CSS animations
were originally thought up, and they rarely have a pointer, and CSS is not really equipped to handle touch events.

It can safely be assumed that 99 % of all real world use cases for animation will be the result of user or server interaction on some
part of the document that is not being animated. The user clicks a button and a div will slide into view. The user
presses a key on his keyboard and text will wiggle and bounce. Data is sent back from an AJAX request, and the received data will
appear through an attention grabbing sliding effect.

Currently the only way to achieve these real world use cases is by adding or removing class attribute values. Thus we have scripts that
will trigger animation in the DOM and the actual design of the animated effects in CSS. Conceptually this is nice. Separation of logic
is a good thing™. However, in real world practice this will not be so neat.

Events confusion

Even though there are no events in CSS, there
is discussion about having animations running upon entering a state,
while being in a state and when leaving a state. These are not events in a technical sense, but outside
of the W3C working group, most developers will be really
confused about the difference. Such precise knowledge is not found
in abundance! If a specific application need to differentiate between these, it is by far easier for developers to use the
more familiar DOM events.

Having some animations run because they are affected directly, e.g. on hover, some animations run because they are triggered by
a scripted change of className, and in both cases also have animations that may run entering, during and
leaving states looks like a recipe for unmaintainable and confusing development. It is way much better to trigger all
events from one place only, and that place can only be the DOM.

How to implement animations in a library

OK, you are building a little library to animate stuff. What do you do? I suppose the following:

First you capability detect support for declarative animation. That in itself would be easier if it was in the DOM, but
it is at least doable now. But not in a neat fashion. Score one against having animations in CSS.

If CSS-animation is indeed supported, you will wrap your animate function around className switches. Doable, but not neat.

If CSS-animation is unsupported, you fall back to old school timed manipulation of the style attribute.

However, using the animation parameters from the CSS-file is a huge impracticality. You must find a way to read all CSS-files,
parse them and interpret the cascade, the specificitivity of all animation rules and convert that information into timed
logic. This is impractical, slow and CPU-draining and fragile.

The CSS Object Model (CSSOM) will not alleviate this problem. Browsers that need to parse the animation rules are the
ones that neither implement animations, nor the corresponding CSSOM.

Alternatively, the author is required to re-specify the animation once again, now using a syntax for the fallback. We thus
get code duplication, with all the error proneness and maintenance problems that follows from that approach.
But it is the only approach currently available with reasonable results.

It can safely be said, that CSS-animations are not backwards compatible in any reasonable way. And we are going to
need backwards compatible solutions for almost another decade or so.

What about progressive enhancement?

Using progressive enhancement we can deliver CSS-based animation to browser that support it, and non-animated but still usable
content to the rest. Problem solved, is it not?

I like progressive enhancement. I
teach it
and I practice it. However, there will be a great number of real world customers that
will insist upon having animations in both the brand new cutting edge browsers and the legacy ones. As least as long as more than
10 % of their visitors use them. We can preach all we want. This scenario will face the real world developer way too often.

Animations will be used to convey information as well as for eye candy. Not having a scripted fall back will not be an
option for such use cases either. In real world web development, progressive enhancement can not be called upon to be a
panacea, how appealing that thought ever may be.

What else will be hard to do using a CSS approach?

In real world use cases developers are also going to want to manipulate animation and keyframe properties, as well as
programmatically create animations from scratch. Using the CSSOM this can probably be done in browser that support animation
but once again the fallback for legacy browsers will be very hard to achieve.

What is my counter proposal

I have barely begun thinking about this issue, so any propsal I have at the moment should not be regarded as a final suggestion.
In order to keep the separation of concern between designers and developers – for those situations where one has the
luxury to keep them separate – animations must be easy to define with a CSS-like syntax.
JSON fits that requirement
quite well. The method to start an animation could be called runAnimation. It might return a value that I can store in a variable
in order to manipulate or cancel the running animation. Another way to manipulate it would be by altering the animation properties.
For convenience, there should also be a method to stop all running animations on an element.

As stated above, my counter proposal is not a finished product in any way. It merely is intended to serve
as an illustration to an alternative approach. The technical merits or defeciencies of that proposal is in
itself not really something that should guide the general discussion about how to implement declarative animation.
The principles on which I draw the conclusion that the DOM is a better fit is the true talking point here.

Now I am especially interested in hearing the opinions from the DOM-scripting community!