Category Archives: CSS

CSS3 Card Flip Animation Trick

I’ve been playing around with some of CSS3’s new animation features. For an app I’m writing, my wife suggested I jazz things up a bit by having an image look like its flipping over, and I realized that with CSS3, I could actually do that. To demonstrate what I’m talking about, in the latest version of Chrome, click one of the playing card images below*.

The neat thing is that the effect is ridiculously simple. The one catch is that you can’t change the background-image property of a div during an animation. To get around this, you just need to use an image that contains all of the pictures you want to display. When the image is out of view (e.g., roated at 90 degrees or 270 degrees on the Y axis), you change the background-position. That way, when the image rotates back into view, it’s displaying a different picture.

It’s pretty simple, but kind of amusing. Below is some example code you can use for your own animations. The card image used in this example can be seen here, and the full set of cards can be obtained here.

CSS:

@-webkit-keyframes card1Flip {
    0% {-webkit-transform: rotateY(0deg);}
    24% {background-position-y:0px;}
    25% {background-position-y:204px;}
    50% { -webkit-transform: rotateY(180deg);}
    75% {background-position-y:204px;}
    76% {background-position-y:0px;}  
    100% {-webkit-transform: rotateY(360deg);}
}
.card1FlipProps {
    -webkit-animation-name: card1Flip;
    -webkit-animation-duration: 2000ms;
    -webkit-animation-timing-function: linear;
    -webkit-animation-iteration-count: 1;	
    -webkit-animation-direction: normal;
    -webkit-animation-delay: 0;
}
#card1 {
    background-image:url('/images/blog-2011/card_map.png');
    width:150px;
    height:204px;
}

JavaScript:

var elm;
elm = document.getElementById("card1");
elm.addEventListener("webkitAnimationEnd", function(){
    if (this.classList) {
        this.classList.remove('card1FlipProps');
    }
}, false);
elm.addEventListener("click", function() {
    if (this.classList) {
        this.classList.add('card1FlipProps');
    }
}, false);

HTML:

<div id="card1"></div>

* Important Notes: Unfortunately, the CSS3 animation module isn’t implemented in most browsers right now, so the above example will only work in the latest version of Chrome. Safari also uses Webkit as its layout engine, however, when I tested this example in the latest version of Safari (5.0.5), it didn’t work correctly. Some digging around showed that my version of Safari was using Webkit version 533.21.1, and my version of Chrome was using Webkit version 534.30.

Since the animation module is still being worked on right now, this technique, and animations in general, should probably be used cautiously and for effects that aren’t that important.