Treehouse

Create a CSS Flipping Animation

By on  

You've all asked for it and now I've added it: Internet Explorer support! Annoyingly enough, the change involves rotate the front and back elements instead of just the container. Skip to this section if you'd like the Internet Explorer code. IE10+ is supported; IE9 does not support CSS animations.

CSS Flip

CSS animations are a lot of fun; the beauty of them is that through many simple properties, you can create anything from an elegant fade in to a WTF-Pixar-would-be-proud effect. One CSS effect somewhere in between is the CSS flip effect, whereby there's content on both the front and back of a given container. This tutorial will show you show to create that effect in as simple a manner as possible.

Quick note: this is not the first tutorial about this effect, but I've found the others over-complicated. Many other tutorials add additional styles to code samples which then require the reader to decipher which are needed and which aren't. This tutorial avoids that issue, providing you only the necessary styles; you can pretty up each side of the flip any way you'd like.

The HTML

The HTML structure to accomplish the two-sided effect is as you would expect it to be:

<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
	<div class="flipper">
		<div class="front">
			<!-- front content -->
		</div>
		<div class="back">
			<!-- back content -->
		</div>
	</div>
</div>

There are two content panes, "front" and "back", as you would expect, but also two containing elements with very specific roles explained by their CSS. Also note the ontouchstart piece which allows the panes to swap on touch screens. Obviously you should break that code into a separate, unobtrusive JavaScript block if you wish.

The CSS

I'm willing to bet that outside of the usual vendor prefix bloat, you'd be surprised at how little CSS is involved:

/* entire container, keeps perspective */
.flip-container {
	perspective: 1000;
}
	/* flip the pane when hovered */
	.flip-container:hover .flipper, .flip-container.hover .flipper {
		transform: rotateY(180deg);
	}

.flip-container, .front, .back {
	width: 320px;
	height: 480px;
}

/* flip speed goes here */
.flipper {
	transition: 0.6s;
	transform-style: preserve-3d;

	position: relative;
}

/* hide back of pane during swap */
.front, .back {
	backface-visibility: hidden;

	position: absolute;
	top: 0;
	left: 0;
}

/* front pane, placed above back */
.front {
	z-index: 2;
	/* for firefox 31 */
	transform: rotateY(0deg);
}

/* back, initially hidden pane */
.back {
	transform: rotateY(180deg);
}

Here's a rough overview of the process:

  • The outlying container sets the entire animation area's perspective
  • The inner container is the element that actually flips, spinning 180 degrees when the parent container is hovered over. This is also where you control the transition speed. Changing the rotation to -180deg spins the elements in the reverse direction.
  • The front and back elements are positioned absolutely so they can "overlay" each other in the same position; their backface-visibility is hidden so the back of the flipped elements don't display during the animation
  • The front element has a higher z-index than the back element so the front element may be coded first but it still displays on top
  • The back element is rotate 180 degrees, so as to act as the back.

That's really all there is to it! Put this simple structure into place and then style each side as you'd like!

A Note from CSS Animation Expert Ana Tudor

Applying certain properties with certain values (like overflow: hidden) on the card element would disallow it to have 3D transformed children. I believe this is relevant because I got into trouble with overflow: hidden precisely in such cases, where all children of the 3D transformed element were in the same plane, but one or more had been rotated by 180deg.

CSS Flip Toggle

If you'd prefer the element only flip on command via JavaScript, a simple CSS class toggle will do the trick:

.flip-container:hover .flipper, .flip-container.hover .flipper, .flip-container.flip .flipper {
	transform: rotateY(180deg);
}

Adding the flip class to the container element will flip the card using JavaScript -- no user hover required. A JavaScript comment like document.querySelector("#myCard").classList.toggle("flip") will do the flip!

CSS Vertical Flip

Performing a vertical flip is as easy as flipping the axis and adding the transform-origin axis value. The origin of the flip must be updated and the card rotated the other way:

.vertical.flip-container {
	position: relative;
}

	.vertical .back {
		transform: rotateX(180deg);
	}

	.vertical.flip-container .flipper {
		transform-origin: 100% 213.5px; /* half of height */
	}

	.vertical.flip-container:hover .flipper {
		transform: rotateX(-180deg);
	}

You can see that the X access gets used, not the Y.

Internet Explorer Support

Internet Explorer requires significant modifications to the standard flip code because it has not yet implemented all of the modern transform properties. Essentially both the front and back elements need to flipped at the same time:

/* entire container, keeps perspective */
.flip-container {
	perspective: 1000;
	transform-style: preserve-3d;
}
	/*  UPDATED! flip the pane when hovered */
	.flip-container:hover .back {
		transform: rotateY(0deg);
	}
	.flip-container:hover .front {
	    transform: rotateY(180deg);
	}

.flip-container, .front, .back {
	width: 320px;
	height: 480px;
}

/* flip speed goes here */
.flipper {
	transition: 0.6s;
	transform-style: preserve-3d;

	position: relative;
}

/* hide back of pane during swap */
.front, .back {
	backface-visibility: hidden;
	transition: 0.6s;
	transform-style: preserve-3d;

	position: absolute;
	top: 0;
	left: 0;
}

/*  UPDATED! front pane, placed above back */
.front {
	z-index: 2;
	transform: rotateY(0deg);
}

/* back, initially hidden pane */
.back {
	transform: rotateY(-180deg);
}

/* 
	Some vertical flip updates 
*/
.vertical.flip-container {
	position: relative;
}

	.vertical .back {
		transform: rotateX(180deg);
	}

	.vertical.flip-container:hover .back {
	    transform: rotateX(0deg);
	}

	.vertical.flip-container:hover .front {
	    transform: rotateX(180deg);
	}

With the code above, IE10 will rotate flip the elements as expected!

The CSS flip animation has always been a classic, representative example of what's possible with CSS animations, and to a lessor extent, 3D CSS animations. What's better is that there's actually very little CSS involved. This effect would be really neat for HTML5 games, and as a standalone "card" effect, it's perfect. Can you think of anything else you'd use this for?

ydkjs-6.png

Recent Features

  • Introducing MooTools&nbsp;Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

  • CSS 3D Folding&nbsp;Animation

    Google Plus provides loads of inspiration for front-end developers, especially when it comes to the CSS and JavaScript wonders they create. Last year I duplicated their incredible PhotoStack effect with both MooTools and pure CSS; this time I'm going to duplicate...

Incredible Demos

Discussion

  1. Sounds cool and all, but its kind of hard to check out a :hover effect when you’re using a touchscreen. #Justsayin’ ;)

    • I’ve updated the post to work on touchscreen Torkil!

  2. As TORKIL JOHNSEN said already. Needs logic for touch devices. The example page does randomly flip the one or other card.
    Besides that, cool stuff.
    Can it be found on github?

    • The post has been updated for touchscreen.

      It’s not on GitHub — all of the code to create the effect is in this blog post.

    • Firstly, this is a really useful effect, thank you Mr. Walsh!

      This might sound odd and most likely has to do with the WP Template I am using, but it is boggling my mind, so here it is –

      I’m working on a client site, which will be live shortly (www.stratacus.com/services/)

      The flipping works great on my Android, however on my iPad – it works a bit sporadically.

      The effect works fine on initial page load, UNTIL I scroll a bit down the page. Once I scroll, I need to press and hold on the image in order to see the flipping effect.

      Upon scrolling more with my finger, touching anywhere to scroll, you can tell that the image wants to flip but it doesn’t… Additionally,

      If I press beneath the picture after scrolling down the page (basically touching where the image was placed on the screen originally, upon initial load at top page height) the picture then flips!

      Very odd behavior and I know it has something to do with the scrolling JS on this template, maybe CSS breakpoints or something, or the template itself somewhere down the line, but I cannot for the life of me wrap my head around it…

      I know it isn’t your functionality that is wrong, but something on my end conflicting with it…

      I will be leaving the effect regardless because, when it does work, it’s awesome, but if you or anyone else has any insight, that’d be more than appreciated and I’ll be forever indebted, just simply because it is really bugging me at this point. (PS I believe by the time someone will be reading this, the site listed above will be live.)

      Thanks again for this great tutorial, any help is appreciated, and feel free to contact me directly if you think you suspect what is causing this.

      Thanks a lot guys,
      – Paul
      paul@unstech.com

  3. A'braham Barakhyahu (@BlessYahu)

    Slick! You can even add a css transition delay so it stays flipped for a little after hovering, which gets close enough to using a click event with javascript.

  4. In Chrome your demos don’t work how you describe. The back is never shown. Rather you just see an exact mirror image of the front.

    e.g. When I flip the basic card, I see “tnorf” not “back”

    • On what platform? Just tested on Mac/Chrome and everything looks correct.

    • I faced the same problem. Worked in Firefox but not in Chrome and Safari. I then went on and added vendor prefixes to all the CSS3 properties such as backface-visibility, transform-style, transition and transform. That sorted it out. Still doesn’t work in Opera and IE9 though.

  5. Yerzhan

    -webkit-transform have some bugs with CSS position:absolute. They can’t work together. Keep in mind.

  6. Jean Azzopardi

    Great article, works smoothly on Mac/Chrome.

    I think this sentence may be wrong though.. “you can’t pretty up each side of the flip any way you’d like.”, or why can’t you, given that you can target .front and .back?

    • Ugh, major typo — that should have said “can.”

  7. James Burgos

    How might this work in a wordpress scenario where posts are displayed in a thumbnail grid where the featured post image is on one side and the post meta is on the other side? how would the permalink work?

  8. Artem Ivanyk

    Hey!

    Nice article, David. However, there are a couple of things we can do to smooth over cross-browser inconsistencies.

    1) There is inconsistency in implementation of perspective property in Firefox 15 and earlier;

    2) Also, in Chrome, when you have a complex markup you can encounter issues with positioned children of the indirectly transformed elements(.front and .back in this case). Absolutely positioned elements would flicker and shine through flipped parent during transform, whereas relatively positioned ones would do likewise and even worse — they’ll ignore parent’s backface-visibility and “shine” through it in mirrored way after transform is complete. Workaround is simple — you have to enable hardware acceleration on the element.

    So, for the above code you would add:

    .flip-container {
         /* 1 */
        /* For Firefox <= 15 to apply perspective. Without these two lines transformation will be flat.
        This fix, however, doesn’t apply if we put overflow property on the element being fixed.
        */
        -moz-transform: perspective(1000px);
        -moz-transform-style: preserve-3d; 
    }
    
    .front {
         /* 2 */
        /*Fix for Chrome, version <= 22*/    
       
          -webkit-transform: rotateY(0deg);
    
        /* or this
        -webkit-transform: translate3d(0, 0, 0);
         any property that triggers hardware acceleration will do the trick
        */
    }
    

    But what about IE? What if we want >=IE10 users to have this cool effect (and I think that right now, we, as web-developers, should care more about IE10 than about IE7 or IE8). It comes with Window 8 this October and it won’t support preserve-3d keyword. How do I know? Because I have W8 running on virtual machine; and they actually were not planning to add it for the release of W8 http://msdn.microsoft.com/en-us/library/ie/hh673529(v=vs.85).aspx (see the note under “Transform-style property” heading).

    Having that said, we need to modify this code a bit. Instead of flipping one wrapper-element, we’re going to flip both sides of the card simultaneously.

    .flip-container {
        -webkit-perspective: 1000;
        -moz-perspective: 1000;
        -o-perspective: 1000;
        perspective: 1000;
    }
    
    .flip-container, .front, .back {
        width: 320px;
        height: 480px;
    }
    
    .flipper {
        -moz-transform: perspective(1000px);
        -moz-transform-style: preserve-3d;
    
        position: relative;
    }
    
    .front, .back {
        -webkit-backface-visibility: hidden;
        -moz-backface-visibility: hidden;
        -o-backface-visibility: hidden;
        backface-visibility: hidden;
    
        -webkit-transition: 0.6s;
        -webkit-transform-style: preserve-3d;
    
        -moz-transition: 0.6s;
        -moz-transform-style: preserve-3d;
    
        -o-transition: 0.6s;
        -o-transform-style: preserve-3d;
    
        -ms-transition: 0.6s;
        -ms-transform-style: preserve-3d;
    
        transition: 0.6s;
        transform-style: preserve-3d;
    
    
        position: absolute;
        top: 0;
        left: 0;
    }
    
    .back {
        -webkit-transform: rotateY(-180deg);
        -moz-transform: rotateY(-180deg);
        -o-transform: rotateY(-180deg);
        -ms-transform: rotateY(-180deg);
        transform: rotateY(-180deg);
    }
    
    .flip-container:hover .back, .flip-container.hover .back {
        -webkit-transform: rotateY(0deg);
        -moz-transform: rotateY(0deg);
        -o-transform: rotateY(0deg);
        -ms-transform: rotateY(0deg);
        transform: rotateY(0deg);
    }
    
    .flip-container:hover .front, .flip-container.hover .front {
        -webkit-transform: rotateY(180deg);
        -moz-transform: rotateY(180deg);
        -o-transform: rotateY(180deg);
        transform: rotateY(180deg);
    }
    
    
    .front {
        z-index: 2;
    }
    

    And don’t forget to add a fallback for browsers which doesn’t support 3d-transform (which is simple if you’re using Modernizr, you just need to describe alternative behaviour using no-csstransforms3d class).

    After all of the above (as of September 2012):
    a) FF 15: applies perspective instead of flattening transformation to 2d;
    b) Chrome 22: works fine if you took care and applied the fix(or if you don’t have to bother about positioning inside the front card);
    c) Safari 5, 6: when it comes to CSS3, there is no browser better;
    d) IE7-IE9: no effect, instant show/hide behavior;
    e) IE10: flat transforms with no perspective. And we’re hoping that when support for 3d-transforms is added, our code is going to work as intended.
    f) Opera 12.02: instant show/hide without the effect, but we’re hoping too =)

    • KurtWM

      Thanks for your IE10 fix, Artem. It was a help!
      http://codepen.io/KurtWM/pen/xhvHe

    • Leet Ice

      Thanks for this.. too bad david walsh can’t update the blog to show how this should be done. Took me an extra 30 minutes to figure this out., until i saw your post.

    • Artem, you’re very insightful and effective comment was a life saver. Was specifically having issues with IE and like Leet Ice, found your code and it fixed my situation immediately.

      David Walsh, please consider updating this post with Artem’s code. Your CSS Flip Animation is wonderful and adds a lot (thank you!), but there are still many people using versions of IE that don’t play nice with it and I’m sure Artem’s code could be invaluable to them if it was easier to see.

    • Thanks Artem, this got David’s code working for me!

    • Amy

      I am trying this out and the code from Artem was great except I can’t figure out how to position more than one container on the same row. I just end up with all the containers stacked vertically on top of one another.

      Can anyone help me figure out what piece of code I can insert to fix this? I am a novice with this stuff and only understand a bit of it so all my attempts have failed.

      Thank you in advance for the help!

  9. Awesome David! Any good way to show the backface-visibility during the animation? Every way I’ve tried has had pretty bad performance/flickering.

  10. This is awesome !
    I add this feature (with little adjustements) on http://datagamer.fr/ ;)

  11. Paul

    I tried changing this to flip on the X axis, but I cannot seem to move the origin to the center. It now flips out the top of the container where the back cannot be seen. Any idea what special sauce I need to add to the CSS?

  12. Keisa

    Anyway we can turn this into a 3D look like this site’s links http://www.pukkelpop.be/nl/bestof ??!!

  13. Hey

    Thx David for nice effect, it gives the site another dimension. Keep up the good work.
    Also thx for Artem,thx to u it works also for me;)

  14. Robert

    Hey David, awesome work! How can I trigger the transition without hover, but by clicking a button or something?

    • Create a class with the :hover selector properties, then add that class to the element that should animate.

  15. Galia Ruth

    Hi, how do you change the codes if you want the card to automatically flip by itself, once, without any mouseover/click?

    Please help!!! i have an urgent project due tomorrow!!!

  16. Em K

    Hi,

    I have been trying every imaginable way to make the card slow down when flipping over.
    I would like it to stay “flipped” some second more before turning over again.
    Transition-delay, for example, does not seem to work…

    Does someone here know a way how to do it (make it flip over completely & then stay flipped a bit longer after cursor moves)? Please share :)

    Thanks guys!

  17. Mark

    Hey David, I just made a CSS-animated greeting card where the card comes out of the envelope and everything. I found your examples really helpful. Thanks for posting them! You can see my project at http://markroland.com/project/CSS-greeting-card

  18. Stephen

    Thanks for posting. Really useful. Using it now.

  19. magon

    works for me on firefox, but not on chrome and safari, while your demo works on the 3 of them, any ideas?
    thanks!

    • magon

      Alright, now that i applied all the fixes it works on chrome and safari but bugs on firefox.
      it’s these two that create the difference: with works great on firefox and not on safari chrome, with bugs on firefox
      .flip-container:hover .back, .flip-container.hover .back {
      .flip-container:hover .front, .flip-container.hover .front {

      thanks in advance!

  20. You probably need to prefix perspective, translate, and transform properties to -webkit-.

  21. Jon

    Hi, Nice work!

    What scripts are included for this to work?

    Best,
    Jon

  22. Elly

    I been searching for something simple and understandable like this!

    Question: Can I use this on a commercial site?

    thanks

  23. PERFECT!! That was awesome! I was looking for something like this. THANKS!! :)

  24. Nice.
    Knowledge – add prefixes for demo downloads.
    Thank you!

  25. Does anybody have this working in Chrome on Windows?

    I’ve managed to get results on:

    Mac: Chrome, Firefox, Safari.
    PC: Firefox, Safari

    IE and Opera are a total bust. I find Window’s Chrome bizarre. I’ve got text displayed correctly, but upon flipping, it’s just rotating the text completely instead of showing the hidden div.

  26. Hey,
    Does’nt work for me with the placed css/html. Is there any javascript needed?
    I work on Chrome/Windows. The demo cards rotate well.

  27. Kev

    Hi guys

    Where can I get a working version of this with the vendor preferences because, its just not happening for me on Chrome :(

  28. Hi David,

    Really cool post. I tried it and works well in Firefox, Chrome and Safari but not on Opera or IE9. Is there a way to get it working? At least on Opera?

  29. Neelabh

    Hi,

    I am new to CSS. Could u explain me what is happening in the following lines. I cannot u’stand the work of the selectors.

    .flip-container:hover .flipper, .flip-container.hover .flipper

    Thank you.

  30. Brian Scott

    Hi,

    nice article, clean and simple. One request, when I compare the animation to the live tiles on my windows phone I notice that the windows version actually goes beyond the 180 degrees briefly then eases back into position before facing flush with the user. Is there a way to recreate this with an animations / keyframes declaration?

  31. Thank you, its works amazing. I do only fight with IE10. I was adding the -ms prefixed and it does only rotate the image on first pane on hover. Anyone know how to fix it?

  32. Hi David,
    Thank you for this tuto, I have some issues with touch stuffs.
    It works as a charm on a laptop, but not on iphone.
    Could you take a look at my code if you have 5min to loose :)
    Thank you

  33. In fact, the first touch flips the div but the second dont turn it back.
    Check this on http://www.l1nkus.com from an iphone.

  34. Lex

    Hey David, one question… Is that your code on CodeCanyon? lol Well just had to ask since the codes in the source are the same. The one in CodeCanyon was published not too long ago, and I see the one on this page was published last year.

    http://codecanyon.net/item/flipping-cards-3d-with-jquerycss3/3726635

  35. Jimmy Soho

    I’m trying to get this working with a container that is filling a div 100% height using position:absolute;top:0;left:0;bottom:0;width:300px. Not having much luck.

    The code I’m trying:

    https://gist.github.com/anonymous/5081539

    I expected it to work when I replace “x-effect” with “effect”, but it doesn’t. Anybody knows how to get such a transform working?

  36. stiven gordillo

    no IE

  37. paraz

    thanx. it works nice.. thanks a lot..

  38. Daniel

    Hi,

    I tried to implement this (great tutorial btw). Unfortunately I ran into an issue with background on the div.flipper – Does anybody have a solution to this?

    http://jsbin.com/amokax/1/

    Great work!

  39. Sai

    This isn’t working on internet explorer 9. IE9. Could you please help me out?

  40. Alex

    Thanks David this is awesome, just what I’ve been trying to figure out how to do.

    I do have one question though, is there a simple tweak to keep the transition within its containing div?

    SoundCloud manage to do it with their widgets: https://soundcloud.com/pages/widgets

    Is this a simple modification, if so, could you shed some light on it?

    Thanks! :D

  41. Don’t work with Samsg s4 browser and Samsg s4 Chrome

  42. Barry Denson

    Seems to no longer work in firefox (Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.24) Gecko/20111103 Firefox/3.6.24).

    I’ve tested all the examples and none of them seem to work in FF but work in Chrome and IE.

    Any idea what has changed in FF to break it?

    • Works for me in current Firefox and Firefox Nightly.

  43. Yannick L.

    Hi David,

    Thanks, very useful tutorial! But i’ve still some questions. How can I make this flip-effect clickable instead of the hover effect that’s used in the tutorial? I want to create a simple button and when you click on that, it should flip.

    Can you give me some more info? Thanks!

  44. Santhosh

    Hi David,
    I tried this on few browser, Here is the result.
    Firefox 21.0 – Works Fine
    IE 10 – Flip the text and image, not showing back
    Opera 12.15 – No animation
    Chrome 26.0 – No animation
    Safari 5.1.7 – Works fine

    Hope you can find a fix for IE, Opera and Chrome.

    • Just tried on Chrome 26 on Mac — worked great!

  45. Chetan

    Hi David, Nice work

    Just IE 7,8,9 – i see its not functional. If it works there – it would be great

  46. Ethan

    Thanks for the clear tutorial David!
    Your demos work fine on chrome 26 for me but I cannot reproduce a working version on any browser.

    When I attempt to create my own version, the front and back divs are both viewable all the time, hovering over the div doesn’t initiate any transform. It’s basically a complete fail for me after a few hours of hacking.

    Is there any hidden javascript or extra code that isn’t included in your walk-through demo? It would be nice to see a jsfiddle version with all the code necessary.

    Thanks again for all your work and selfless contributions to the community!!

  47. Ethan

    Argh… please disregard the above comment. Got it working by adding the appropriate vender prefixes to the css.

  48. Rennan

    Thanks for the clear tutorial David!
    I have a question about CSS3 animations. Is there a way to build this animation without using hover or click functions? I´m new using css3 and want to study animations like transitions, to use in games.

    • Sure Rennan. You would use CSS animations (via keyframes) and then add and remove CSS classes with the animation settings on them.

  49. I rewrote this without using preserve-3d, because Internet Explorer 10 does not support that keyword at this time (Source: http://msdn.microsoft.com/en-us/library/ie/hh673529.aspx). If anyone is interested, my code is available as a GitHub Gist here: https://gist.github.com/smockle/5550032 (CSS and SCSS available).

    • Oskar

      Big thanks! Took some browser sniffing to solve my problem. But it is solved!

  50. Semih

    great tutorial. i am working on a card game and i wanted to use this code but didnt figure out how to set flip animation with “onclick” function. can anyone help me ?

  51. Wei

    This is broken for me in the newest Chrome Canary (29.0.1507.0). The back side of the card doesn’t appear when flipped. Anyone else see this?

  52. Celso Santos

    @Semih, Yeah, I was also trying to use a click event to set the motion in action, but I jus’t can’t find a way to do it. Tried using an eventListener, but I’m not getting any luck…

  53. Celso Santos

    @Semih and everyone else who want to have to flip effect activated by clicking, it’s as simple as instead of having ‘.flip-container:hover .flipper’ just rename the class to ‘.flip-container .selected .flipper’ or any other name you see fit and then just have that style applied with click events..

  54. I’m testing some ideas on my dev space and would really like to use this to flip from one image to another. I’m using WordPress and just cannot get this to work – could you help please?! Apologies, I am a complete novice…!

  55. I had nothing but trouble in Chrome 25, even after adding vendor prefixes.

    I went with this $6 solution on CodeCanyon, mentioned above, and finally got it to work:

    http://codecanyon.net/item/flipping-cards-3d-with-jquerycss3/3726635

    Highly recommended – tons more features including automatic, timed animations, different flipping directions, etc.

  56. I have same issue with the chrome Version 27.0.1453.110 m. “The back side of the card doesn’t appear when flipped. Anyone else see this?”
    I have used this flip effect from my product page. Please help.

  57. I used your instructions for a personal project, I only added this thing to work with IE10 and touch devices:

    onmspointerdown =”javascript:this.classList.toggle(‘hover’);”

    it seems that ontouchstart doesn’t work with IE ( i know, I shouldn’t worry about MS anymore). I left both, but don’t know if that’s correct.

    • John

      Dear Gabirel

      You’re probably using css reset file.
      I recommend to test without css reset.

  58. Rob

    Having a strange issue. I am testing a mobile design for my businesses website, and the flip works with hover when I use Safari on my desktop and use the iPhone user agent (to get the proper style sheet).

    However, when using it on the actual iPhone device, it flips on the first tap, but does not flip back on the second tap. The same thing happens in Chrome on my Galaxy Note 2 with taps, HOWEVER #2, if I use the S-Pen (which allows for hovering), the flip works both ways just as it does with :hover on the desktop browsers.

    I am using using the inline “ontouchstart” code just like your example. in fact, all of the CSS i am using is identical to your example, just with renamed classes. Not sure what the problem is, since the code is exactly the same as on your demo page, other than the Width being 100% instead of pixels.

    i also added a javascript alert for touchstart (using jquery ON), to see if the .hover class is being removed properly, and it is. It almost seems like the CSS is not properly updating once the class is removed.

    http://monarchmotel.com/rooms/the-boat-room/?theme=monarch2013

    • Rob

      I may be running into other issues now. It is a great effect, but i’ll probably skip it for my mobile site for right now (your own demo is having weird issues on my Android phone with Chrome, but not with Safari on my iPhone, weird).

  59. fenix

    can anybody help me with ie9 and the actuall chrome versions doesnt flip it to the back.
    thy

  60. On transition delay.
    Can anybody help to add the code so that the flipped side remains after having hoovered.
    I tried multiple ways but can’t quite figure what’s going wrong. Thanks.

  61. Hi David
    this looks amazing
    I’m currently working on iPad/iPhone apps that could use this exact feature, but coding is not my strong suit – i’m having a little trouble applying it to my imagery and allowing the interactivity

  62. Hassan

    Dear David !
    Please tell something about IE ? how it can be work on IE because without IE this work is useless for developers.

  63. David, this is sooo cool. Thanks for sharing this priceless trick!

  64. It took me awhile to get this through to live but I figured you might like to see how I implemented this.
    I even made it degrade to a tool tip for browsers that can’t handle this.
    https://store.enmasse.com/tera

  65. Sam

    In SASS:

    // Entire container, keeps perspective.
    .flip-container {
      width: 100%;
    
      &:hover .flipper, &.hover .flipper {
        // Front pane, placed above back.
      	.front {
          @include transform(perspective(1000px) rotateY(-179.9deg));
      	}
      	// Back, initially hidden pane.
      	.back {
          @include transform(perspective(1000px) rotateY(0));
      	}
      }
    
      .flipper {
        position: relative;
      }
    
      .front, .back {
      	position: absolute;
      	left: 0;
      	top: 0;
      	width: 100%;
    
      	@include backface-visibility(hidden);
        @include transform(perspective(1000px) rotateY(180deg));
        @include transition-duration(0.6s);
    
        // Front pane, placed above back.
        &.front {
          z-index: 2;
          @include transform(perspective(1000px) rotateY(0));
        }
      }
    }
    
  66. Dragos

    Any idea how to make this work with 3 flip faces (not 2 like there). I need it like this:
    First face
    Toggle button -> Second face
    Second toggle button -> Third face

  67. MWill

    Hey there,

    and thank you for the awesome css effect!
    I tried using this in combination with my first steps into flexible layouts, where I have multiple divs of different %width and %height dimensions relative to the browser viewport (think metro ui style tiles). Is there a way this might work without the absolute pixel dimensions in the “.flip-container, .front, .back” classes?

    Thank you in advance!
    Kind regards,
    MWill

  68. Mela

    It works perfectly! Thanksies!

  69. hello,
    is there a way to make the image a link still using this css?

  70. Thanks, David! This tutorial is flipping easy :)
    I’ve used it (verbatim, for the most part) to add a shuffle button to my photo website.
    Take a look when you can!

    And thank you.

  71. Oops. The website is at http://www.blindinglyordinarythings.com
    You can see the styled css flip on any of the photo pages.

    Thanks!

  72. tex

    hi, nice tut and work… but is there an option to have the flip animation but with two different sides, not just one side flipping around ?

    thanks in advance

  73. there are some mistakes in the code but all in all very nice :-)

  74. yep this is a real pain in the backface-

    one way to resolve, when the anim has finished just set display none on the rear facing element. You have to set display block again before initiating the next animation. Not great but fixes it.

  75. Kristin

    Hello! I love this script – thanks so much for posting it!
    I too am trying to make the images flip using a mouse click rather than a hover. I read through the comments and still couldn’t figure out how to do it.
    I tried using javascript and changed my :hover states to .flip-container.hover .front and .flip-container.hover .back, gave my flip-container div this property:

    and added this javascript:

    function hoverthis()
    {
    if (this.className == 'flip-container hover') {this.className='flip-container'}
    else { this.className='flip-container hover'}
    }
    

    But I keep getting errors and it just isn’t working for me. Anyone have any ideas?

  76. Thomasine Stonecypher

    This is the right website for anybody who wants to learn more about this topic. You understand so much understanding it is hard to not to agree with your viewpoint — not that I really would like to. You definitely put a new spin on a subject that has been written about for ages. Wonderful content!

  77. valeri

    hi dont know if the source code is corect if i use it it dont work but this css those frome the demo: for tohose who it wont work on crome or safari

    /* simple */
    		.flip-container {
    			-webkit-perspective: 1000;
    			-moz-perspective: 1000;
    			perspective: 1000;
    
    			border: 1px solid #ccc;
    		}
    
    			
    			.flip-container:hover .flipper, .flip-container.hover .flipper, #flip-toggle.flip .flipper {
    				-webkit-transform: rotateY(180deg);
    				-moz-transform: rotateY(180deg);
    				transform: rotateY(180deg);
    				filter: FlipH;
        			-ms-filter: "FlipH";
    			}
    
    		.flip-container, .front, .back {
    			width: 320px;
    			height: 427px;
    		}
    
    		.flipper {
    			-webkit-transition: 0.6s;
    			-webkit-transform-style: preserve-3d;
    
    			-moz-transition: 0.6s;
    			-moz-transform-style: preserve-3d;
    
    			transition: 0.6s;
    			transform-style: preserve-3d;
    
    			position: relative;
    		}
    
    		.front, .back {
    			-webkit-backface-visibility: hidden;
    			-moz-backface-visibility: hidden;
    			backface-visibility: hidden;
    
    			position: absolute;
    			top: 0;
    			left: 0;
    		}
    
    		.front {
    			background: lightgreen;
    			z-index: 2;
    		}
    
    		.back {
    			background: lightblue;
    			-webkit-transform: rotateY(180deg);
    			-moz-transform: rotateY(180deg);
    			transform: rotateY(180deg);
    		}
    
    		.front .name {
    			font-size: 2em;
    			display: inline-block;
    			background: rgba(33, 33, 33, 0.9);
    			color: #f8f8f8;
    			font-family: Courier;
    			padding: 5px 10px;
    			border-radius: 5px;
    			bottom: 60px;
    			left: 25%;
    			position: absolute;
    			text-shadow: 0.1em 0.1em 0.05em #333;
    
    			-webkit-transform: rotate(-20deg);
    			-moz-transform: rotate(-20deg);
    			transform: rotate(-20deg);
    		}
    
    		.back-logo {
    			position: absolute;
    			top: 40px;
    			left: 90px;
    			width: 160px;
    			height: 117px;
    			background: url(logo.png) 0 0 no-repeat;
    		}
    
    		.back-title {
    			font-weight: bold;
    			color: #00304a;
    			position: absolute;
    			top: 180px;
    			left: 0;
    			right: 0;
    			text-align: center;
    			text-shadow: 0.1em 0.1em 0.05em #acd7e5;
    			font-family: Courier;
    			font-size: 2em;
    		}
    
    		.back p {
    			position: absolute;
    			bottom: 40px;
    			left: 0;
    			right: 0;
    			text-align: center;
    			padding: 0 20px;
    		}
    
    		/* vertical */
    		.vertical.flip-container {
    			position: relative;
    		}
    
    			.vertical .back {
    				-webkit-transform: rotateX(180deg);
    				-moz-transform: rotateX(180deg);
    				transform: rotateX(180deg);
    			}
    
    			.vertical.flip-container .flipper {
    				-webkit-transform-origin: 100% 213.5px;
    				-moz-transform-origin: 100% 213.5px;
    				transform-origin: 100% 213.5px;
    			}
    
    			.vertical.flip-container:hover .flipper {
    				-webkit-transform: rotateX(-180deg);
    				-moz-transform: rotateX(-180deg);
    				transform: rotateX(-180deg);
    			}
    	
    
  78. Subject: IE 10 Problem
    This is really great and I have it working with chrome. I took the code from the demo which Valeri posted and that fixed it in CHROME, but, it would not rotate at all in IE 10. I then applied changes offered by Artem Ivanyk. Those changes caused it to rotate 360 degrees really fast in CHROME. Great if you want a subliminal message in CHROME. In IE 10, it rotates 180 degrees but the back side is in reverse. The print is backwards. If anyone has this working in IE 10 AND CHROME please post the solution. I could use it. Also, the current Demo as of this post is not working with the IE 10 version provided with all Windows 8 computers.

  79. Hi David,
    thanks for the nice article. In Firefox and Safari it looks nice (2D and 3D, respectively). But on my iPad (retina) the vertical flip seems broken.
    Please check out this screenshot: http://www.borislau.de/files/vertical_flip.jpg
    Do you already have a fix for this?
    Best, Boris

  80. janka Mifsud

    Hi I wanted to see if there is way to get the image to flip every 10 seconds on its own?

  81. valeri

    and is there a ie 10 fix il be happy if it wil flip as long it dose somthing

  82. hi. very thank you . it was very helpful for me

  83. Is it possible to make the flipped image be a link? So that on a mobile device tapping the image flips it and that image is then tappable as a link?

  84. KurtWM

    Great article! Artem Ivanyk, your input came in handy as well when it came time to get my animation working in IE10. Here it is and it works in IE10, Firefox and Chrome. I haven’t tested in Safari. This version animates itself, rather than using hover.

    http://codepen.io/KurtWM/pen/xhvHe

  85. Gitesh

    Can you tell me whether this code released for use under a particular license?

  86. dany

    I’m trying to create a nice Responsive CSS flipping effect on a banner. I only want the effect to occur on the left side image.

    here is the html:

    <!-- front content -->
    <a href="http://ispeedzone.com" rel="nofollow">
    <img class="fblogo1" border="0" alt="iSpeedzone" </a>
    
    <!-- back content -->
    <a href="http://ispeedzone.com" rel="nofollow">
    <img class="fblogo1" border="0" alt="iSpeedzone" </a>
    
    <img class="fblogo2" border="0" alt="iSpeedzone" 
    

    here is the CSS:

    images{
    
    width: 100%;
    }
    
    img.fblogo1 {
    width: 100%;
    float: left;
    display: inline-block
    }
    
    img.fblogo2 {
    width: 88.5%;
    float: right;
    display: inline-block
    }
    
    /* entire container, keeps perspective */
    .flip-container {
    -webkit-perspective: 1000;
    -moz-perspective: 1000;
    -o-perspective: 1000;
    perspective: 1000;
    }
    
    .flip-container, .front, .back {
    width: 34%;
    height: auto;
    }
    
    .flipper {
    -moz-transform: perspective(1000px);
    -moz-transform-style: preserve-3d;
    
    position: relative;
    }
    
    .front, .back {
    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -o-backface-visibility: hidden;
    backface-visibility: hidden;
    
    -webkit-transition: 0.6s;
    -webkit-transform-style: preserve-3d;
    
    -moz-transition: 0.6s;
    -moz-transform-style: preserve-3d;
    
    -o-transition: 0.6s;
    -o-transform-style: preserve-3d;
    
    -ms-transition: 0.6s;
    -ms-transform-style: preserve-3d;
    
    transition: 0.6s;
    transform-style: preserve-3d;
    
    
    position: absolute;
    top: 0;
    left: 0;
    }
    
    .back {
    -webkit-transform: rotateY(-180deg);
    -moz-transform: rotateY(-180deg);
    -o-transform: rotateY(-180deg);
    -ms-transform: rotateY(-180deg);
    transform: rotateY(-180deg);
    }
    
    .flip-container:hover .back, .flip-container.hover .back {
    -webkit-transform: rotateY(0deg);
    -moz-transform: rotateY(0deg);
    -o-transform: rotateY(0deg);
    -ms-transform: rotateY(0deg);
    transform: rotateY(0deg);
    }
    
    .flip-container:hover .front, .flip-container.hover .front {
    -webkit-transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
    -o-transform: rotateY(180deg);
    transform: rotateY(180deg);
    }
    
    .front {
    z-index: 2;
    }
    

    How can I make it work so that the left image will also flip when hovering over the right side image ? (while keeping both images responsive)

  87. I sent you an email earlier today regarding a question for a responsive 2 image flip CSS. Forget about it. I figured it out by myself. Thanks for your help anyways.

  88. Karsten Ohme

    Awesome!

  89. Good job, David!

    I’m trying to implement it on a page, and when I manage well enough.

    What I want to achieve is that the animations can also be made at the time of loading the page.

    Can you do?

    If so, you would be so kind to tell me how it could be done?

    Thank you!

  90. I can’t get this to work on Firefox. I feel like I added the correct prefixes but I’m new to this. The animation just keeps flipping back and forth. Works on Safari and Chrome. Demo: http://www.wienerwedding.com/wedding_party — I’m already live, please help!

    /* entire container, keeps perspective */
    .flip-container {
        -moz-perspective: 1000;
    	perspective: 1000;
    }
    /* flip the pane when hovered */
    .flip-container:hover .flipper, .flip-container.hover .flipper {
    	-moz-transform: rotateY(180deg);
    	transform: rotateY(180deg);
    }
    
    .flip-container, .front, .back {
    	width: 320px;
    	height: 480px;
    	margin: 10px 0 10px 0;
    
    }
    
    /* flip speed goes here */
    .flipper {
    	-moz-transition: 0.6s;
    	transition: 0.6s;
    	-moz-transform-style: preserve-3d;
    	transform-style: preserve-3d;
    
    	position: relative;
    }
    
    /* hide back of pane during swap */
    .front, .back {
    	-moz-backface-visibility: hidden;
    	backface-visibility: hidden;
    
    	position: absolute;
    	top: 0;
    	left: 0;
    	-webkit-box-shadow:
    	0px 0px 0px 2px rgba(0,0,0,0.6),
    	0px 0px 0px 14px #fff,
    	0px 0px 0px 18px rgba(0,0,0,0.2),
    	6px 6px 8px 17px #555;
    
    	-moz-box-shadow:
    	0px 0px 0px 2px rgba(0,0,0,0.6),
    	0px 0px 0px 14px #fff,
    	0px 0px 0px 18px rgba(0,0,0,0.2),
    	6px 6px 8px 17px #555;
    
    	box-shadow:
    	0px 0px 0px 2px rgba(0,0,0,0.6),
    	0px 0px 0px 14px #fff,
    	0px 0px 0px 18px rgba(0,0,0,0.2),
    	6px 6px 8px 17px #555;
    }
    
    /* front pane, placed above back */
    .front {
    	z-index: 2;
    }
    
    /* back, initially hidden pane */
    .back {
    	-moz-transform: rotateY(180deg);
    	transform: rotateY(180deg);
    	background-color: #99CCFF;
    }
    
    .flip-container {
    	-webkit-perspective: 1000;
    	-moz-perspective: 1000;
    	-o-perspective: 1000;
    	perspective: 1000;
    	margin: 20px 26px 32px 26px;
    }
    
    .flip-container, .front, .back {
    	width: 240px;
    	height: 240px;
    }
    
    .flipper {
    	-moz-transform: perspective(1000px);
    	-moz-transform-style: preserve-3d;
    
    	position: relative;
    }
    
    .front, .back {
    	-webkit-backface-visibility: hidden;
    	-moz-backface-visibility: hidden;
    	-o-backface-visibility: hidden;
    	backface-visibility: hidden;
    
    	-webkit-transition: 0.6s;
    	-webkit-transform-style: preserve-3d;
    
    	-moz-transition: 0.6s;
    	-moz-transform-style: preserve-3d;
    
    	-o-transition: 0.6s;
    	-o-transform-style: preserve-3d;
    
    	-ms-transition: 0.6s;
    	-ms-transform-style: preserve-3d;
    
    	transition: 0.6s;
    	transform-style: preserve-3d;
    
    
    	position: absolute;
    	top: 0;
    	left: 0;
    }
    
    .back {
    	-webkit-transform: rotateY(-180deg);
    	-moz-transform: rotateY(-180deg);
    	-o-transform: rotateY(-180deg);
    	-ms-transform: rotateY(-180deg);
    	transform: rotateY(-180deg);
    }
    
    .flip-container:hover .back, .flip-container.hover .back {
    	-webkit-transform: rotateY(0deg);
    	-moz-transform: rotateY(0deg);
    	-o-transform: rotateY(0deg);
    	-ms-transform: rotateY(0deg);
    	transform: rotateY(0deg);
    }
    
    .flip-container:hover .front, .flip-container.hover .front {
    	-webkit-transform: rotateY(180deg);
    	-moz-transform: rotateY(180deg);
    	-o-transform: rotateY(180deg);
    	transform: rotateY(180deg);
    }
    
    
    .front {
    	z-index: 2;
    }
    
    
    • Prince Chaudhary

      Paul, instead of writing

      .flip-container {
          -moz-perspective: 1000;
      	perspective: 1000;
      }
      

      you can write

      .flip-container {
          -moz-perspective: 1000px;
      	perspective: 1000px;
      }
      

      and it will work fine.

      Just add px to the value.

  91. Robert

    For the toggle flip, what would the jQuery script look like?

  92. its very good, but i cant see to get the right/bottom border outside of the image prior to hover

  93. Toddy

    Don’t works in IE10 & 11. Any idea how I can only display the backside in IE10 and up?

  94. Nate Zander

    Hi David-

    I updated OS X to Mavericks last night and noticed my version of your card flip code was broken on my development site in Chrome 31. I spent the past hour trying to figure out what was wrong, so I came back to your original article and realized the demo no longer works on your site either! Have you noticed/heard of any issues with Mavericks (10.9) and Chrome 31?

    The demo works perfectly in Safari.

    Thanks!

    -Nate

  95. Sotiris Iliadis

    Hello everyone! I am trying to apply a horizontal flip effect but it doesn’t work. I believe that there is a problem with the backface-visibility. Please help! Here is the code:

    .flip-container{
    perspective:1000;
    }
    
    .flipper{
    -webkit-transition:2s;
    -webkit-transition-delay:0,01s;
    transform-style:preserve-3d;
    position:relative;
    }
    
    .flip-container:hover .flipper{
    transform:rotateY(180deg);
    -webkit-transform:rotateY(180deg);
    opacity:0;
    }
    
    .flip-container, .front, .back{
    width:960px;
    }
    
    .front, .back{
    backface-visibility:hidden;
    position:absolute;
    }
    
    .back{
    transform:rotateY(180deg);
    }
    
    .front{
    z-index:2;
    }
    
  96. Great read once again David,

    How would you go about making this responsive?

    Or is there possibly anywhere this has already been made responsive I can see working for help?

    Many thanks

  97. Dan

    Has anyone adapted this to flip through a calendar which has images above and month below: i.e., each page is a double-side printed, but all files are individual.

  98. Hi David, awesome tutorial. How do I ad some zoom along with flip ? Just like in iOS skype application.

  99. Christopher

    Hi, I’m new and I have a question. Can your CSS flip technique be used on header or P tags ?

  100. I found it working on Chrome with the code of Valeri look at my sample at http://theweeblytricks.weebly.com/8.html

  101. Great love it

    not working on IE 11 down though!

    FML!

  102. I’ve used this method on my websites some months ago and it was working normally, anyway currently it doesn’t work anymore, even in the david page it is not working as supposed, the back content is not displayed correctly, anyone has a fix for it? I tried managing opacity and z-index but the back content pops up without transition… too ugly…

  103. Jason Purdy

    This doesn’t seem to be working with Chrome (33.0.1750.46 beta on Ubuntu) where it flips, but the backside doesn’t show up.

  104. Criss

    Of the few 3d flip effects available on the web, this one is the best and easiest because it doesn’t use jquery. But it doesn’t work on IE, which is a major fallback. I wonder why is Codecanyon’s version working for all IE versions whereas here we are still struggling for the solution.

  105. Criss

    … There seems to be a solution for all browsers: http://css3playground.com/3d-flip-cards/
    But even if it seems simple, it is very difficult to adapt to David’s script (at least I haven’t managed so far).

  106. Criss

    Probably everybody knows this (I didn’t): jQuery animations use the computer’s hardware, while CSS3 transitions and animations use the browser’s rendering engine. This is one of the reasons that jQuery animations work on some browsers that don’t support CSS3 transitions.
    So that’s the reason why David’s script doesn’t work in Explorer. Though it seemed to be its best feature, its ability to work only with CSS and no Jquery is its weakest point!

  107. Quick note: This post has been updated to accommodate for Internet Explorer and now works in all browsers!

    • Tom

      I’m trying out your demo in IE9 and it doesn’t seem to work at all. Did you try IE9?

  108. Vincent Pelletier

    Thanks for the demo!
    I’m a novice in css (so correct me if i’m wrong) but i think i discovered something in your demo that could be wrong: if the perspective value has no unit, the perspective effect doesn’t apply to Firefox (tested in Firefox 26 & 27). The flip effect does work though.
    If you append an unit to the value (“1000px”), the perspective effect is applied in Firefox.

  109. Vincent Pelletier

    I hoped that the code in my previous comment would be formatted as, for exemple, in the Sotiris Iliadis comment. It didn’t worked as planned ;-)
    Can someone tell me how to format code in comments?
    Thanks.

  110. Hi David and all,
    I’m a big fan and follower of your stuff and this code rocks!
    I wanted to share with you my implementation of this on a commercial site I have just worked on.
    With some nifty additions one can achieve also a delayed effect on nested flippers, check out the front page here and hover over the larger image grids!
    http://www.outdoorequipped.com/
    Works in all the latest browsers!
    Thanks so much for the clean and understandable coding – really cool – CSS is becoming ever so powerful now :)

  111. Charlie

    I am interested in this effect for my WordPress site that I am working on, but have no knowledge on how or where to put this code for this flip animation. Any and all help would be appreciated – where do I place this code, etc. A “CSS For Dummies” explanation will be helpful (if possible) – again, no knowledge on how to code, just the very basics!! Thx.

  112. This is great! In regards to mobile, the current script works with touch events but how about when there are multiple boxes with this effect.

    Situation:
    I’m doing a list of services with this card effect. Each card will have a title and image of an individual service on the front, and a description on the back. How can I customize the script to flip previous viewed card to the front position while clicking the next card to view the back.

    Thanks.

  113. Vivek

    Hi David,

    Thanks for this wonderful post. Had a question.

    Is there a way to find out in script which side (front or back) is visible at a given time?

    • Of course, you can check the value of the transform property. If the value is rotateY(180deg);, you’re seeing the back.

  114. Kimberly Randall

    Hi David,
    This works great for me on desktop; however on iPad if I tap a tile and it flips & then links to another page, when you “go back” to the original page, the tile is still flipped. Is there a way to have the tiles in their original state on “go back”?

  115. Kimberly Randall

    Hi David,
    I was just following up on my comment above sent on the 25th; is there a fix for that bug?

    ********
    This works great for me on desktop; however on iPad if I tap a tile and it flips & then links to another page, when you “go back” to the original page, the tile is still flipped. Is there a way to have the tiles in their original state on “go back”?
    ********

  116. lukas

    it is worth mentioning, that this code only works as nice if it is put in style tags directly inside the page. If it is in a css file maybe even with an import, you end up with a weird flick when the page loads. E.g. the content of front and back is loaded first, and then gets initially animated to flick the back to the back

  117. Andrew

    It just wont work for me in Chrome, Safari, Opera – only firefox or IE. Is there something I’m missing – all CSS looks fine to me as updated but can’t get it to work. I think others have had issues but I simply cant see where it is coming from. The front and back content is flipping verically – I’m not sure if this makes a difference?

    Otherwise happy with results! Just want it to work in multiple browsers. CSS here:

    .flip-container {
    	perspective: 1000;
    	transform-style: preserve-3d;
    	position: relative;
    }
    .back {
    		transform: rotateX(180deg);
    }
    .flip-container:hover .back {
    	transform: rotateX(0deg);
    }
    .flip-container:hover .front {
        transform: rotateX(180deg);
    }
    .flip-container, .front, .back {
    	width: 275px;
    	height: 59px;
    }
    .flipper {
    	transition: 0.6s;
    	transform-style: preserve-3d;
    	position: relative;
    }
    .front, .back {
    	backface-visibility: hidden;
    	transition: 0.6s;
    	transform-style: preserve-3d;
    	position: absolute;
    	top: 0;
    	left: 0;
    }
    
    z-index: 2; transform: rotateY(0deg); .back {
    	transform: rotateX(-180deg);
    }
    

    Thanks in advance!

  118. Having failed getting it to work (Vendor Prefixes), viewing, copying and pasting source of the demo then modifying it looks amazing! Thank you.

  119. Hello!

    The code works perfect. But when having multiple instances. On tap flips two a time.

  120. Mark

    Cool effect and tutorial, thanks… I have a problem using many of this together on the same line…
    they are always placed one under the previous, not on the same row.
    any help?

  121. Mark

    ‘float: left’ solved my previous question ;-)

  122. Earlier you stated you could make this an on demand effect with a javascript css class assignment. however, when I tried that it didn’t work. I think I’m getting confused by the fact that you consolidate a lot of classes and states in a single css declaration. I have the effect working on hover in all the browsers I have tested in but I’d like to bind it to a button. Any clarification you could provide on your code would be most helpful.

  123. Daniel Cohen Gindi

    Man, about the “overflow:hidden” stuff – you are completely wrong.
    If overflow:hidden works badly for you – it is because your container has a zero width/height. Because your “cards” have position:absolute, they do not set their parent’s dimensions.

  124. Jason

    Can you give an example of a clickable link on the back of your example?

  125. Very radical David going to try and implement this right now.

  126. This is awesome, I will be using this for our about page sections. I can’t believe how easy it is too! I am so impressed with CSS3 animations lately, way less complicated and less buggy then js.

  127. Hey, is it possibble to make it flip to a random card.

    So i can make a random card generator and every time i flip to back it will show a new random card?

  128. visitor

    There’s a lot missing on this page compared to the examples and it’s not just vendor prefixes. Works ootb in Firefox, but Chrome is a nightmare.

  129. Can anyone help me get this CSS Flip code to work. Much Appreciated. http://production.macniche.com/

  130. Im trying to get this simple CSS 3 Flip animation to work. But it’s not working for me. Can anyone help me? It would be appreciated. I copy the exact code for my css file which is flip.css and used the exact hml provided.
    http://production.macniche.com/ I would even pay for help. Thanks.

  131. Wei

    Drew, the flip animation is working for me on your site using the latest Chrome and Chrome Canary. Which browser are you using?

    • I’m willing to be that Drew isn’t adding CSS prefixes.

  132. Bo

    Awesome example. Took me while to find the right code that will work on IE. I’m baffled at how your example works in IE 9 and IE 8? I’m looking at it through IE 10 emulator. Your example works but mine doesn’t. I just copied your code. Is there additional js or polyfill used?

  133. agon

    Completely buggy in the new Firefox 30 and Nightly 33 and Aurora 32. Soooo…doesn’t work with any of the new firefox releases.

  134. Thanks for this awesome code.
    It worked perfectly in FF, but it wouldn’t work for others… so I fixed it.
    This version is for JavaScript controlled flipping, based on a user’s choice, not hover enabled!

    /* entire container, keeps perspective */
    .flip-container {
    	perspective: 1000;
        transform: perspective(1000px);
        -webkit-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
    	transform-style: preserve-3d;
    }
    	/*  UPDATED! flip the pane when hovered */
    	.flip-container.flip .back {
            -webkit-transform: rotateY(0deg);
            -o-transform: rotateY(0deg);
            -ms-transform: rotateY(0deg);
            -moz-transform: rotateY(0deg);
    		transform: rotateY(0deg);
    	}
    	.flip-container.flip .front {
            -webkit-transform: rotateY(180deg);
            -o-transform: rotateY(180deg);
            -ms-transform: rotateY(180deg);
            -moz-transform: rotateY(180deg);
    	    transform: rotateY(180deg);
    	}
    
    .flip-container, .front, .back {
    	width: 320px;
    	height: 480px;
    }
    
    /* flip speed goes here */
    .flipper {
    	transition: 0.6s;    
        transform: perspective(1000px);
        -webkit-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
    	transform-style: preserve-3d;
    
    	position: relative;
    }
    
    /* hide back of pane during swap */
    .front, .back {
        -webkit-backface-visibility: hidden;
        -o-backface-visibility: hidden;
        -ms-backface-visibility: hidden;
        -moz-backface-visibility: hidden;
    	backface-visibility: hidden;
    	transition: 0.6s;
        -webkit-transform-style: preserve-3d;
        -o-transform-style: preserve-3d;
        -ms-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
    	transform-style: preserve-3d;
    
    	position: absolute;
    	top: 0;
    	left: 0;
    }
    
    /*  UPDATED! front pane, placed above back */
    .front {
    	z-index: 2;
        -webkit-transform: rotateY(0deg);
        -o-transform: rotateY(0deg);
        -ms-transform: rotateY(0deg);
        -moz-transform: rotateY(0deg);
    	transform: rotateY(0deg);
    }
    
    /* back, initially hidden pane */
    .back {
        -webkit-transform: rotateY(-180deg);
        -o-transform: rotateY(-180deg);
        -ms-transform: rotateY(-180deg);
        -moz-transform: rotateY(-180deg);
    	transform: rotateY(-180deg);
    }
    
    /* 
    	Some vertical flip updates 
    */
    .vertical.flip-container {
    	position: relative;
    }
    
    	.vertical .back {
            -webkit-transform: rotateX(180deg);
            -o-transform: rotateX(180deg);
            -ms-transform: rotateX(180deg);
            -moz-transform: rotateX(180deg);
    	    transform: rotateX(180deg);
    	}
    
    	.vertical.flip-container:hover .back {
            -webkit-transform: rotateX(0deg);
            -o-transform: rotateX(0deg);
            -ms-transform: rotateX(0deg);
            -moz-transform: rotateX(0deg);
    	    transform: rotateX(0deg);
    	}
    
    	.vertical.flip-container:hover .front {
            -webkit-transform: rotateX(180deg);
            -o-transform: rotateX(180deg);
            -ms-transform: rotateX(180deg);
            -moz-transform: rotateX(180deg);
    	    transform: rotateX(180deg);
    	}
    
  135. edmund

    Firefox 30 now also needs the MSIE10+ code to work.

  136. Jade

    Finally a code that works!

    How can I flip the entire container? at the moment just the front and back flip. I have added a shadow to the container which gives the look of a card, so I would like to flip the whole lot.

  137. Awesome bit of code so thanks for posting. I did get an issue with Firefox though and pin pointed the issue to the:

    .front { z-index:2; }
    

    The issue was that the front image just flipped and didn’t show the back image. Removed this css and it works as it should. Fine on the browsers i’ve tested.
    The issue only happened on the site i’ve built so its one i’ve put in, but thought i’d share just incase others get the issue!

    Thanks again!

  138. Hi.. nice effect.. But on windows phones you gotta touch and hold for it to flip, and on release it flips back.. Is there any way to make it flip just by touching it like on other touch devices (without holding it down)?
    Any help will be appreciated.. thanks

  139. Caley Walsh

    Love this code, thanks very much David.

    I am hoping someone can help me with changing mine so each block rotates onclick rather than hover. I’m really not sure what I need to change and what javacript to add to my page to make it work…hint and tips would be greatly appreciated.

    http://pixelperfectdesignstudio.com/pibworth/?page_id=56

  140. Great work!

    Only a little mistake, in

    .front {
    	z-index: 2;
    }
    

    should be:

    .front {
    	z-index: -2;
    }
    

    http://stardesign.com.pl/blog/

  141. Raj

    Hi,

    I want to add three face in a card and two flip it two times. plz help me in implement this.

    Thank you.

  142. Keshav

    Hi
    I have tried your code. For me it is working fine in IE, Chrome and Firefox. but not working in Windows safari. I have tested your demo page also. it is working fine in Mac Safari. but not working in Windows safari.

    The issue is, In windows safari browser front face only flipping, backface is not visible.

    Please help me to fix this issue.

    Thanks in Advance

  143. Dom

    Strange bug in the current Chrome: Once flipped, the .back shows ok, however only the right hand side of the .back div (exactly down the middle, pixel perfect) accepts any pointer-events. I have a centred link and only the right half of it is clickable (or even shows the pointer cursor)? Anybody else seen this?

  144. Rob

    Newest Firefox (31) just need this to work again!

    .front {
    	z-index: 2;
    	transform: rotateY(0deg);
    }
    
    • bzeiler

      THANK YOU SO MUCH!

  145. Anyone having an issue with the text being blurry when the transition has finished?

  146. This is a fantastic trick, just had a look at the demo. Gonna have a go at this later on my new ipad and see what I can flip! Thanks

  147. Rafael
     Hi! How can you change the Hover to something like a "onclick"? 
    • For a dirty css-only solution you could use the active class, but you’d have to keep it pressed to see the animation complete…

       
        .flip-container:active .flipper,  
        .flip-container.active .flipper
      

      Better go with js adding a specific class that starts the animation as David described in his post.

  148. Hi, looks like this animation is a bit touchy in regard to browser z-index code updates :) , the version below have been tested on the latest builds available september 2014:
    * Chrome 37 – works 100%
    * Firefox 31 – works 99%, sometimes a side is partially covered by a background color overlay, likely caused by my .front/.back content
    * Safari 7.0.6 – works 100% (was having the same issue of @Keshav with the original code, this one works)

    I’m displaying a complex canvas editor with selectable/resizable elements on each side, if you were having issue with elements not responding to click events anymore (see @Dom above), this version fixes that too.

    .flip-container {
      -webkit-perspective: 1000;
      -moz-perspective: 1000;
      -o-perspective: 1000;
      perspective: 1000;
    }
    
    .flip-container:hover .flipper,  
    .flip-container.hover .flipper  {
      -webkit-transform: rotateY(180deg);
      -moz-transform: rotateY(180deg);
      -o-transform: rotateY(180deg);
      transform: rotateY(180deg);
    }
    
    .flip-container, .front, .back {
      width: 640px;
      height: 480px;
    }
    
    .flipper {
      -webkit-transition: 0.6s;
      -webkit-transform-style: preserve-3d;
      -moz-transition: 0.6s;
      -moz-transform-style: preserve-3d;
      -o-transition: 0.6s;
      -o-transform-style: preserve-3d;
      transition: 0.6s;
      transform-style: preserve-3d;
      position: relative;
    }
    
    .front, .back {
      -webkit-backface-visibility: hidden;
      -moz-backface-visibility: hidden;
      -o-backface-visibility: hidden;
      backface-visibility: hidden;
      position: absolute;
      top: 0;
      left: 0;
    }
    
    .front {
      z-index: 2;
      /* for firefox 31 */
      transform: rotateY(0deg);
    }
    
    .back {
      -webkit-transform: rotateY(180deg);
      -moz-transform: rotateY(180deg);
      -o-transform: rotateY(180deg);
      transform: rotateY(180deg);
    }
    
  149. Thanks for this article. I am using this with content divs and not images. When doing this, I encountered a weird issue where elements on the left hand side of the “back” would not be clickable. To fix this, it looks like translateZ(1px) has to be added. I found the solution here: http://stackoverflow.com/questions/10886656/webkit-transform-blocking-link

    Cheers!

  150. Fabz

    For some reason it is not working in IE in my end. Only Chrome. Please help, I’ve tried all the suggestions above.

  151. supz

    Hi David,
    Thanks for fantastic article. I have used it in my current project. Its working perfectly on all the browsers. But…, when I access this flip from safari which is in a virtual machine, it is very inconsistent.You can test your demo in safari + VM (windows7).

  152. TJ

    I haven’t found a CSS card flip yet that can work inside of a table. Do you know the reason for this?

  153. Billy

    I have this implemented on a site that I’m working on right now. Great work on this. Only problem is when I insert the IE fix, it breaks the Chrome/Firefox functionality. Also, after implementing IE fix, text on the “back” of card is all backwards. Do I need to reference a different stylesheet in order to load IE fix and any way I can fix backward text? I’m using Dupal Omega subtheme. I wish IE would just go away. LOL. Any ideas on how to solve this?

  154. Jaan

    Hi.
    I have some troubles with it:
    1) ontouchstart=”this.classList.toggle(‘hover’);” won’t validate.

    2)when using then the 3d animation will disable

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!