Animating CSS class changes with D3

In a previous blog post I discovered that using .style(“fill”, …) to set colors was way, way slower than using .attr(“class”, …) to just switch the class. Which is all well and good, but what if I want to animate the color change? Ie: not just switch from white to black but use D3 transitions to show the grey between? Here are some options.

Class hackery: create a bunch of CSS classes “grey0”, “grey1”, “grey2”, … that are a ramp from black to white. Then set .attr(“class”, greyN) with a tweening function that uses the classes. Seems awfully inelegant and hard to get right, particularly when you consider nonlinear easing functions.

Stylesheet manipulation. You can grab the CSS stylesheet itself and modify it. I found one D3 example. I have read lots of admonishments that modifying the CSS is hacky, flaky,  and works differently in different browsers. No idea if this would be suitably fast; I can’t imagine browsers optimize this usage.

CSS transitions. Nominal support is pretty good, although I’m breaking my rule not to use vendor prefix CSS in my projects (stupid WebKit). Something as simple as rect { -webkit-transition: fill 0.4s } looks pretty good in Chrome. It does not look good in Firefox: it doesn’t seem to actually tween the color so really all you get is a 0.4s delay. No idea how it looks in Opera or IE. Oh well, I design for WebKit anyway.

CSS transitions have nice control over the easing function. However I don’t see any control over the interpolation, something that’s quite important and subtle when tweening colors. The spec says it interpolates in RGBA space which is just about the worst possible choice. Fortunately my example is tweening white and bright yellow, so I can get away with it, but a red to blue tween probably looks awful using CSS.