Tag Archives: chrome

structural animation in HTML5 + CSS3

I was cooking up a new search preview control lately and came across a very interesting idiom in HTML5/CSS3 that seems like one of those small technical details that indicates how we code web apps is about to change radically. This JSFiddle demonstrates what I consider to be an interesting and possibly important breakthrough in UI frameworks.

If you run the fiddle on a Chrome browser you’ll see an image. If you hover your mouse over the image, you’ll see something like the below:

Screenshot showing a user interface consisting of a picture of a "Tintin" statue with an array of images fanned out behind it like a deck of cards.

A control for showing a set of images in the effective space of one image. The user can “spin” the deck so that cards are rapidly rotated through the top position, allowing rapid preview of set contents. When the mouse moves away, the “deck” smoothly stacks up under the top image. see the demo

You’ll notice (on Chrome) that the cards in the background start out hidden, then animate smoothly out into the fan shape shown above.

There’s more: click on the top image and it will smoothly fade while flying towards you, the rest of the deck will smoothly rotate up with each card taking the place of the previous one, the original will reappear smoothly at the bottom – allowing infinite cycling – and everything happens at the best frame rate your machine can produce. On a MacBook Pro, it’s a solid 60 frames per second. It’s an entrancing effect, tuned to the nearest millisecond. In one of my apps I have it hooked to scrolling and it runs like recombinant mercury.

Here’s the interesting part: the code that runs when you click (or scroll) looks like this:

box.prev = function() {
$div.append($div.children(“.page”).first().remove());
}

This is superficially JQuery, but the practitioner will recognize that JQuery is not being used for animation. What this says is:

“remove the first child of the div and put it onto the end of the div”

In other words, a purely structural statement. There are no pointers to the top page, no “firstHiddenPane” variables keeping track of things, no ad-hoc circular buffer implementations. There is literally zero presentation logic for this arguably state-of-the art control.

This control’s behavior is built entirely in CSS3. You might expect the appearance – the static image – to be in CSS, but here a fairly complex set of dynamic state is being managed by the CSS engine with high GPU utilization** While we have been approaching this kind of architecture for quite some time in CSS, I think this example implementation represents a threshold in the evolution of the model wherein some large, complex, and hard-to-master user interface constructs suddenly become easier to build on JS/HTML/CSS than on any other UI platform – and promise to run with optimal performance characteristics on modern and future OS platforms.

As an example, I’m rewriting a fairly large and sophisticated view control to use this technique and finding the already-heavily-refactored code to be reduced by more than 50%. At the same time, it’s getting faster by a large measure. The code is also getting far prettier, always a key indicator.

More to share in a future prototype. Love to hear your thoughts about this technique – is it really something new, or just another idiom?

If you don’t want to parse the code, the key CSS concepts used are nth-child, transition, and transform. The insight was how they work together: more on this in a later post, if you can stand not to tinker it out yourself.

* all currrent-gen browsers can do this technique, but cross-browser CSS3 (including all variants) would be much harder to read. For my production work, I typically use a script called -prefix-free from Lea Verou that automatically inserts the right browser prefixes dynamically at runtime.

* certainly all the discrete visual elements are loaded onto GPU “surfaces;” with a suitable set of shaders, the position and opacity values could easily be interpolated on the GPU, meaning all the CPU-side CSS engine would need to do would be to switch shader parameters on the DIV’s surfaces

Advertisements
Tagged , , , ,