Monday, February 23rd, 2009

Building a presentation experience using CSS transitions and animations

Category: CSS

JavaScript guru extraordinaire Erik Arvidsson has been playing with the new CSS transitions and animations that WebKit lead out with.

He decided to build a sample presentation system:

It is interesting to see the three versions that he builds.

First, he uses CSS animations and @keyframes, and all that goodness, but for what he was doing it had drawbacks:

The CSS animations has a few drawbacks. One of them is that when the animation is finished it is pretty cumbersome to freeze the state. One way to achieve the freezing is to listen to the window.onwebkitanimationend event , check the animationName of the event, read the computed style and apply that. The problem with this is that I either iterate over all CSS properties used in the to (100%) keyframe or I manually keep track of the properties I want to freeze. I ended up manually setting the properties because I was laze. This does not scale well of course so if you are serious about freezing your animations I would recommend writing functions to freeze the animation (you will need to be able to unfreeze it if you want to animate it again).

He then realised that CSS transitions was the better approach for this use case:

Transitions allow you to change a CSS property (any property that supports transitions) and it will animate the property when changed. For example, if you say that “width” should be a transition-property, setting the width will animate the width from its old width to the new width. I cannot emphezise enough how useful this property is. Please reread this paragraph and makes sure you get it :-) Now how many lines of js do you need to make your elements fade in and out when you show and hide them? None, it is easily done with one line of CSS (if you use opacity to hide them that is).

So back to the KeyNote like demo. The idea here is to set all the coming cards to zoomed out and totally transparent and all the previous cards to zoomed in and transparent. Now you only need to change which element is current by setting the zoom to 100% and the opacity to 1. Done!

That is not entirely true, I also updated the class name of the previous and next card.

Finally, he cleaned up shop a little with the little known :target selector:

This is an iteration on the previous one. Instead of defining .next, .current and .previous classes I realized I could use the :target CSS selector in combination with the next sibling selector. The :target selector matches any element with the same id as the hash fragment of the URL. This is mostly used for highlighing the target of an internal anchor that was clicked but it can be used for other more fancy things (like tab panes for example).

When the page loads I needed to ensure that the URL contained a hash fragment and if it didn’t I replaced the URL with one that did. Also, I needed to add some code to sync the current card with the hash, allowing the user to bookmark the correct card. A feature that should be part of any sane web app.

Posted by Dion Almaer at 1:51 am
Comment here

3.8 rating from 22 votes

Comments Here »

Comments feed TrackBack URI

Leave a comment

You must be logged in to post a comment.