CSS Card Flip using Webkit Transitions

Webkit brought a lot of enhancements to the formerly dull browser based user interfaces, with transform and transition properties being among the most useful for user interaction.

In this tutorial we will learn how to use both to create a product card that flips to reveal more information with a fallback for browsers that don’t support Webkit transitions and transform.

CSS Card Flip Demos

There are three examples for this tutorial, each one with its own advantages.

Card flip triggered by click

Card flip triggered on mouse over

Card flip triggered by disjoint button

The first two are the most basic: you have to either click on the card or roll your mouse over it to trigger the effect. The last one has a link on the image, that jumps to another site, and a button overlayed on top, which is the one that triggers the card flip.

The main difference between the “click to flip” example and the other two is that you can’t have a link within the faces unless you deal with event propagation and it’s not the focus of this tutorial. Read the good article on Quirks Mode to know more about JavaScript events.

In turn, the difference between the card flip triggered by a mouse over event and the one triggered by a button is that you can’t have a link on the front face. Well, you can, but every time you try to click it you will first trigger the mouse over event and thus the card will flip. With an additional button you can have a link on the front face and still be able to flip the card.

What about Firefox, Opera or the one browser whose name is written in the Black Speech of Mordor?

For all these browsers the sample code will perform a swap between the front and the back face, simply by swapping the layer’s depth. So easy and safe that it even works in You Know Who 5.5.

HTML structure of the card

To keep things really simply, I’ve stripped out most of the markup that is used for presentational issues. Refer to the source code of each example to get the full code for each one.

The layout is very simple: a div that acts like the card body and two divs, one for each face.

<div id="block" class="block" onclick="changeClass()">
<div class="front side">
<img src="image.jpg" alt=""/>
<div class="back side">
<p>Some text</p>

Notice that whenever the class is clicked it will call a changeClass function. This is the trigger for the first example. The third example uses the changeClass function but it’s placed in the link for the button. In the second example the card flip is purely CSS-driven and doesn’t call a function: it’s simply activated by a :hover pseudo selector.

Swapping classes with JavaScript

For the first and third example, the changeClass function simply adds or removes a class with javascript, depending on the current classes added to the element, which is referenced by its ID attribute.

function changeClass(){
if(document.getElementById("block").className == "block"){
document.getElementById("block").className += " rotated";
document.getElementById("block").className = "block";

Styling the card flip

Again, everything that is purely ornamental has been removed to focus on the functionality.

height: 360px;
width: 620px;
position: relative;
-webkit-perspective: 500;
.block {
position: absolute;
height: 260px;
width: 320px;
left: 50px;
top: 50px;
-webkit-transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1.5s;
-webkit-transform: rotateY(180deg);
position: absolute;
-webkit-backface-visibility: hidden;
-webkit-box-shadow: 0 2px 5px #666;
height: 260px;
width: 320px;
height: 280px;
width: 180px;
padding: 10px;
-webkit-transform: rotateY(180deg);

The Webkit properties used here for the card flip are:

-webkit-perspective: adds depth to make the element to appear to be in a 3D space. Otherwise the flip looks like a horizontal stretch. Required only for presentational purposes.

-webkit-transform-style: propagates the 3D perspective for the faces to move into this 3D space. This is better appreciated in the disjoint button example. If you flip the card without this property, the back face is entirely affected by the link of the image in the front face. This occurs because all the layers are collapsed and placed one within the other in the usual HTML markup flow. Required? yes, this is an essential property.

-webkit-transition: sets the animation for the card flip. Required? Yes, otherwise it’s not a card flip: the card simply toggles between the front and back faces.

-webkit-transform: essential property to actually rotate the card.

-webkit-backface-visibility: this property will hide backface of the front or the back face when applied. It’s essential for the effect, otherwise the content of the opposite face can be seen through.

A Card Flip? Why and when?

Ok so we now know how to create a card flip using Webkit’s transforms. But should we use it? Certainly. For example, if you have an app with a lot of buttons grouped together, instead of showing 16 buttons at the same time, you could organize them in discrete blocks of 4 buttons using the hover sample and show only 4 icons to the user: when the user rolls the mouse over one of the sets, the blocks flips and the four buttons are revealed for the user to select one.

A card flip also saves screen real state: you could have a user card and display the name, an avatar and the user’s website URL on the front and a short biography on the back with links to other social profiles. Otherwise you would have to use twice the space to show all this.

Finally, it looks good! Download the file and play with it, have fun.

26 thoughts on “CSS Card Flip using Webkit Transitions”

  1. CSS Card Flip using Webkit Transitions…

    Learn how to create a CSS 3 Card Flip using Webkit’s transforms and transitions, including a fallback for Firefox, Opera, IE or other non Webkit browsers….

  2. looks/works great in chrome & safari, not so much in firefox 3.6.17, oh well. if only i had more advanced clients. thank you for continuing to push the envelope.

  3. Card flip is not working on windows 7 machine with latest version of Google chrome. Could you please tell me the reason why it is not working on windows 7 machine. Let me know if i need to upload screenshot or video for the same.

  4. Hi, is there any chance to show two cards side by side, where the user has to choose one of them and in case of an click, flip them both?


  5. Is there any way to give the container div 100% width and height? I can make the other divs dynamic but when I change the container element, the flip card doesn’t display

  6. I´ve found the perfect flip solution 😀 First I had another idea on how to do the flip trick but yours is way better^^

    Greetings from germany!

  7. I want to insert this function into my wordpress page, but it is breaking the site. I’ve tried placing the script into header.php and my function.php files.

  8. Is there a way to make this work for multiple cards floated next to each other? I can only make one of them contained within a larger flip at a time.

  9. Great code, but I too am having problems duplicating the boxes to create multiple. Any ideas? Thanks.

  10. So the fix was actually pretty easy; give each instance of the flip card a unique id, both in your html file and your js file.

    For example:


    function changeClass1(){ if(document.getElementById(“1”).className == “block”){ document.getElementById(“1″).className += ” rotated”;
    else{ document.getElementById(“1”).className = “block”;

    function changeClass2(){
    if(document.getElementById(“2”).className == “block”){
    document.getElementById(“2″).className += ” rotated”;
    else{ document.getElementById(“2”).className = “block”;

  11. Ah Whitney. I wasn’t far off then. I did try this, looks like the only part I missed was the (“1”) section. That’s cheered me up. Thanks Whitney!! 🙂

  12. I do trust all of the concepts you have introduced for your post. They are very convincing and can certainly work. Nonetheless, the posts are very brief for beginners. May you please extend them a bit from next time? Thank you for the post.

Leave a Reply