CSS3 Card Flip backface disappears at end of transform - css

I've gotten a simple set of cards that I need to flip on click. The problem is that when the transform is done the backface (blue side) disappears. It kind of shows up during the animation back to the front-face.
I know it's probably a simple solution and something simple, but it might not be. I can replicate the results in Chrome (Canary) and Safari.
I've tried some things with backface-visibility that allow it to not disappear but then I can click it with the jQuery listener and have it flip back to the front.
Here is the fiddle: http://jsfiddle.net/9gPfz/1/
Here's the CSS: `.equipment-card-holder{
-webkit-perspective: 1000;
}
.equipment-card{
height: 250px;
width: 222px;
background: #fff;
box-shadow: 0 1px 5px rgba(0,0,0,0.9);
float: left;
margin: 0 9px 30px;
-webkit-transform-style: preserve-3d;
-webkit-transition: all 1s ease-in-out;
transition: all 1s ease-in-out;
}
.equipment-card .card-face{
-webkit-backface-visibility: hidden;
position: absolute;
width: 100%;
height: 100%;
}
.equipment-card .card-front{
-webkit-transform: rotateY(0deg);
}
.equipment-card .card-back{
-webkit-transform: rotateY(180deg);
background-color: lightBlue;
}
.equipment-card.flipped{
-webkit-transform: rotateY(180deg);
box-shadow: 0 15px 50px rgba(0,0,0,0.2);
}
.span12{
width: 960px;
}
}`
You will need a webkit based browser for the vendor prefixes I am using.

Ok so I figured out the problem, and yes it was simple. The problem is that I had a background color set on the card (vs on both faces of the card). I hope this answer my prove useful to someone in the future who may be Googling with this issue.
Edit: More exact answer
css:8 remove the background of the card
background: #fff;
And just just put background to the face
Can check the update of the same fiddle http://jsfiddle.net/9gPfz/2/

I was doing a similar thing but the accepted answer did not work for me. So I tried some other hacks.
What's happening is that the background of the "back" class is somehow overridden by the background of the "flipped" class.
It can be corrected by adding a background: transparent; on the flipped class.
Mind you this is not a perfect solution. Just a workaround.
.equipment-card.flipped{
-webkit-transform: rotateY(180deg);
box-shadow: 0 15px 50px rgba(0,0,0,0.2);
background: transparent;
}
Checkout the updated fiddle here: http://jsfiddle.net/9gPfz/28/

None of the existing answers worked for me. I had a child element on the front of the card that was disappearing upon flipping it.
<div class="front">
<div class="mytext">
{{data.text}}
</div>
</div>
To fix it, I had to add the transform property to the child as well.
.front {
transform: rotateY(180deg);
display: flex;
justify-content: center;
align-items: center;
-webkit-backface-visibility:hidden;
backface-visibility:hidden;
.mytext {
transform: rotateY(0deg);
z-index: 1;
}

Related

Weird trailing effect during css animation

I am creating an animation while I got this weird issue. Below is a code snippet with a single div with some styles and animation applied to it.
When I run the code, during the animation, I can see a weird trailing effect on the extreme right side of the square.
*{
margin: 0px;
padding: 0px;
}
body{
background-image: radial-gradient(pink, hotpink);
height: 100vh;
width: 100vw;
display: flex;
justify-content:center;
align-items: center;
}
#keyframes zoominout{
0%{
transform: scale(1.0);
}
50%{
transform: scale(1.1);
}
100%{
transform: scale(1.0);
}
}
#outer{
border: 2px solid black;
height: 450px;
width: 450px;
animation: zoominout infinite 4s;
}
<div id="outer"></div>
Whenever I click anywhere or press any button, the trails disappear.
What could be causing this and how should I solve this issue?
Also, this issue occurs only with borders. Without borders, no issue is there.
Update - This issue is with chrome browser only. While using firefox, no trailing lines are visible.
It appears to be your borders that are scaling but somehow remain behind in faded form.
If we take a more minimal example - no border radius, no flexing, you can see it clearly on this square. The first has animation duration 4s and shows separate lines which is what you get but in small form on the circle. The second has animation duration 40s and show more continuous as would be expected as more frames would be possible in the time.
Here's the snippet:
<style>
#keyframes zoominout{
0%{
transform: scale(1.0);
}
50%{
transform: scale(1.1);
}
100%{
transform: scale(1.0);
}
}
#outer{
border: 2px solid black;
border-color: magenta;
height: 450px;
width: 450px;
animation: zoominout infinite 4s;
background-color: cyan;
}
</style>
<div id="outer"></div>
So, what to do about it? Somehow the borders aren't totally disappearing but are fading.
Update: here's a quick workaround - animating dimensions rather than scaling. I know it's not the best way to animate (as it possibly isn't using the GPU???) but it seems to work. Of course you'd want to put your circle (now a square) into a container which has the actual width and then use %s. It worked on Chrome, Edge, Firefox on Windows 10 and Safari and Chrome on IOS14. It also removed the slight flicker that was previously seen on Firefox and Safari [which had both worked better on the initial code than Edge or Chrome on Win10].
Snippet with workaround:
<style>
*{
margin: 0px;
padding: 0px;
}
body{
background-image: radial-gradient(pink, hotpink);
height: 100vh;
width: 100vw;
display: flex;
justify-content:center;
align-items: center;
}
#keyframes zoominout{
0%{
width: var(--w);
height: var(--w);
}
50%{
width: calc(var(--w) * 1.1);
height: calc(var(--w) * 1.1);
}
100%{
width: var(--w);
height: var(--w);
}
}
#outer{
--w: 450px;/* you don't have to use a CSS variable but this is just to make it easier to change the width/height if you need to */
border: 2px solid black;
height: var(--w);
width: var(--w);
animation: zoominout infinite 4s;
}
</style>
<div id="outer"></div>

Transform and Stacking Order

I am trying to understand what is really happening “3d” world of CSS.
I made a simple example
Particularly the code which bugs me the most is:
.back {
background-color: tomato;
transform: rotateY(180deg);
z-index: 1;
}
The thing which is not clear to me is why when you hover over .inner, its background color (gold) is not visible?? If you remove the transform property from .back or if you set the rotateY to 0deg then the gold background color of the .inner is clearly visible.
Why is the transform property of .back changing the stacking order?
Logically it makes sense that children(.front and .back) should appear in front of their parent(.inner).
Also, I would like to know what really happens when you set transform-style to flat? Does that make parent and all of its children collapse into single “unit” where element with highest stacking order takes priority/visibility?
in your code :
.outer {
display: block;
width: 200px;
height: 200px;
border: 2px solid gold;
perspective: 1000px;
padding: 10px;
margin: 0 auto;
}
.inner {
position: relative;
height: 100%;
width: 100%;
transition: transform 2s linear;
transform-style: preserve-3d;
background-color: gold;
backface-visibility: visible;
transform: rotateY(50deg);
}
.sides {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
color: white;
backface-visibility: hidden;
}
.front {
background-color: blue;
transform: translateZ(20px)
}
.back {
background-color: tomato;
transform: rotateY(180deg) translateZ(10px);
}
.inner:hover {
transform: rotateY(180deg)
}
<div class="outer">
<div class="inner">
<div class="sides front">Front Side</div>
<div class="sides back">Back Side</div>
</div>
</div>
you are using
transform: rotateY(180deg) translateZ(10px);
The transforms are applied right to left, so first it goes to the front 10px. But after that, it rotates 180deg. (around the transform-origin that is constant). That makes the previous 10px go towards the back instead of to the front.
if the order is the inverse
transform: translateZ(10px) rotateY(180deg);
now the rotation is done first, and so the translation is unafected by it and goes to the front.
and No, sorry, z-index is not a substitute for 3-d transforms, if you want to use 3d transforms, translation is the only way to go ....
In your first example, z-index is useless, as can be seen easily
codepen with z-index removed
This works because you are setting
backface-visibility: hidden;
So only the face that is facing front will be visible

Smooth CSS rotate animation on hover

I've create a button, and I want it to rotate 360deg on mouse hover, and rotate backwords 360deg on hover off. So far it work well, but if you go slowly towards it with the mouse, it flickers.
Here's the short version of the code:
.btn {
display: block;
margin: 60px auto;
width: 250px;
padding: 15px;
position: relative;
color: #3498db;
font-weight: 300;
font-size: 24px;
text-decoration: none;
border: 5px solid #3498db;
transform: rotate(360deg);
transition: all 0.5s;
transition-timing-function: cubic-bezier(1, 0.8, 0.5, 1);
}
.btn-rotate:hover {
transform: rotate(0deg);
transition-delay: 0;
transition: all 0.5s;
}
I am a button!
for full code, check the codpen demo http://codepen.io/andornagy/pen/ojBNZx
The flicker issue is happening because, when you hover on the element, the elements start to rotate. After rotating some x degree, the element would've rotated to certain degree and the mouse/cursor is not anymore on the element.
This is the reason the flicker is happening.
Comparing to the above one, I feel using wrapper (div) and analyzed how much width we may need, we set that to div. On div:hover element, we can perform the transition. It gives better result compared to now.
Here is the fiddle
.buttonHolder {
padding: 50px;
}
.buttonHolder:hover .btn-rotate {
transform: rotate(360deg);
transition-delay: 0;
transition: all 0.6s;
}
Here's an idea where it adds an extra pseudo element only when you're hovering :
Demo
.btn:after {
content: '';
width: 300px;
height: 150px;
display: none;
position: absolute;
top: 50%;
left: 50%;
border-radius: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.btn:hover:after {
display: block;
}
Gave it a bit of background color, just so it's better visible what's going on...
For the most control, I'd resort to some JavaScript though.

Higher level CSS animation library?

I looked around but can't find any good resources for doing higher level animations (like card flip, cubes, etc). Like a ???:CSS :: jQuery:JS.
I know of transit but I'm looking for something that has more functionality and animations built in.
Have you thought about using Animate.css? Seems pretty good. Another good one seems like CSS3 Animations and for stuff like card-flipping, CSS3 Playground.
An edited version of this one: http://css3.bradshawenterprises.com/flip/:
JSfiddle: http://jsfiddle.net/PnUHr/1/
CSS
#f1_container {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
}
#f1_container {
-webkit-perspective: 1000;
perspective: 1000;
}
#f1_card {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: all 1.0s linear;
transform-style: preserve-3d;
transition: all 1.0s linear;
}
#f1_container:hover #f1_card {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
box-shadow: -5px 5px 5px #aaa;
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.face.back {
display: block;
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
box-sizing: border-box;
color: white;
text-align: center;
background-color: #aaa;
}
HTML
<div id="f1_container">
<div id="f1_card" class="shadow">
<div class="front face">
<img src="Cirques.jpg"/>
</div>
<div class="back face center">
<img src="Cirques.jpg" style="transform:scaleX(-1), transform:scaleY(-1)"/>
</div>
</div>
</div>
All credits go to the original created (see link). I've just removed the padding that was on the back-facing <div> and added a mirrored background of the front-facing image.
For Mozilla/Gecko browsers you need to add the -moz-* prefixes too. Same for Opera (-o-*) and Internet Explorer (-ms-*`).
Direct image link: http://css3.bradshawenterprises.com/images/Cirques.jpg
Effeckt.css is STILL work in progress but look very promising– a pattern libary of multiple sources.

CSS3 perspective in 3D

I'm having a problem with CSS 3D perspective property.
<figure>
<img src="http://www.saintbioz.fr/wp-content/uploads/2010/02/paysage-montagneux.jpg" width="512" height="384" alt="Landscape" />
<figcaption>Summer in the mountains</figcaption>
</figure>
I just want to animate the figcaption at :hover to perform a folding-down effect (like http://davidwalsh.name/demo/folding-animation.php) from -90deg to 0deg , considering that -90deg represent the block flatten (and so not visible)
/** vendor prefixes have been removed for better readability **/
figure {
display: inline-block;
position: relative;
line-height: 0;
perspective: 300px;
}
figcaption {
background-color: rgba(0,0,0,0.2);
padding: 20px 10px;
position: absolute;
top: 0;
right: 0;
left: 0;
transition-property: all;
transition-duration: 500ms;
transform: rotateX(-123deg);
transform-origin: top;
}
figure img:hover + figcaption {
transform: rotateX(0deg);
}
The problem is that perspective does not give the same render for Chrome and Firefox.
I had to set manually the figcaption default transform to rotateX(-123deg); depending of the perspective value which is 500px, and it works well on Chrome, but not on Firefox.
Theoretically, it should be -90deg when not :hover and 0deg when :hover, but seems that the perspective attribute changes the length of the depth field and so -90deg does not works anymore.
I wonder what are the best practices when playing with perspective and rotate in order to make it works well on all recent browsers ?
Best regards.
PS: Just copy/paste the HTML & CSS and try it in Chrome and FF, you should immediately see what's wrong ;)
I know it won't be helpful, but personnaly I tried some experiments with perspective and each browser render the perspective in a different way. Some browsers don't support the perspective. So, your application won't be accesible to everyone, maybe you should use another technology until all of the main browsers are fully compliant with the perspective.
Probably it's too late for this answer to be useful.
Anyway, the best way to make the element invisible is to keep the angle at 90deg, but set the perspective origin to be just above it. (No need to figure the exact angle that will get the desired effect)
figure {
display: inline-block;
position: relative;
line-height: 0;
perspective: 300px;
perspective-origin: top center; /* added this setting */
}
figcaption {
background-color: rgba(0,0,0,0.2);
padding: 20px 10px;
position: absolute;
top: 0;
right: 0;
left: 0;
transition-property: all;
transition-duration: 2s;
transform: rotateX(-90deg);
transform-origin: top;
}
figure img:hover + figcaption {
transform: rotateX(0deg);
}
<figure>
<img src="http://www.saintbioz.fr/wp-content/uploads/2010/02/paysage-montagneux.jpg" width="512" height="384" alt="Landscape" />
<figcaption>Summer in the mountains</figcaption>
</figure>

Resources