I'm trying to implement a flip on an image but its preserve 3d (or probably backface-visibility) is not working on ie11.
This solution didn't work for me: -webkit-transform-style: preserve-3d not working
Here is a pen for you to try stuff and also a fiddle: http://codepen.io/vandervals/pen/XbedKY?editors=110
.container {
-ms-perspective: 1500px;
perspective: 1500px;
}
.canvas {
position: relative;
width: 300px;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50% 0;
transition: transform 1s ease 0s;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
overflow: visible;
}
.canvas img {
max-width: 100%;
backface-visibility: hidden;
position: relative;
z-index: 2;
}
input:checked + .canvas {
transform: rotateY(180deg);
}
.red {
background: red;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
backface-visibility: hidden;
transform: rotateY(180deg);
}
<div class="container">
<input type="checkbox">
<div class="canvas">
<img src="http://todofondosdeamor.com/wp-content/uploads/images/48/gatitos-1__400x300.jpg">
<div class="red"></div>
</div>
</div>
<p>That checkbox over there</p>
Internet Explorer doesn't support preserve-3d in any version (probably Spartan will).
You need to change the way you have set the transforms if you want it to work (on the item directly instead of the container)
.container{
perspective: 1500px;
}
.canvas{
position: relative;
width: 300px;
transform-origin: 50% 50% 0;
transform-style: preserve-3d;
overflow: visible;
}
.canvas img{
max-width: 100%;
backface-visibility: hidden;
position: relative;
z-index: 2;
transition: transform 1s ease 0s;
}
input:checked + .canvas img {
transform: rotateY(180deg);
}
.red{
background: red;
width: 100%;
height: 100%;
position: absolute;
top:0;
left:0;
z-index: 1;
backface-visibility: hidden;
transform: rotateY(180deg);
transition: transform 1s ease 0s;
}
input:checked + .canvas .red {
transform: rotateY(360deg);
}
<div class="container">
<input type="checkbox">
<div class="canvas">
<img src="http://todofondosdeamor.com/wp-content/uploads/images/48/gatitos-1__400x300.jpg">
<div class="red"></div>
</div>
</div>
<p>That checkbox over there</p>
Related
I want to rotate my element repeatedly, without back flip. When I call my function first time it will rotateX('180deg'), and the second will be rotateX('360deg') but the problem when I call third time it will be backflip, so any idea to make this flip keeping forward without back flip?
function myFunction() {
if (document.getElementById("front").style.transform == "" || document.getElementById("front").style.transform == "rotateX(0deg)") {
document.getElementById("front").style.transform = "rotateX(180deg)";
document.getElementById("back").style.transform = "rotateX(0deg)";
} else if (document.getElementById("front").style.transform == "rotateX(180deg)") {
document.getElementById("front").style.transform = "rotateX(360deg)";
document.getElementById("back").style.transform = "rotateX(180deg)";
} else {
document.getElementById("front").style.transform = "";
document.getElementById("back").style.transform = "rotateX(-180deg)";
}
}
.flipcard {
position: relative;
width: 220px;
height: 160px;
perspective: 500px;
}
.flipcard.h .back {
transform: rotateX(-180deg);
}
.flipcard .front,
.flipcard .back {
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
transition: all 0.5s ease-in;
color: white;
background-color: #000;
padding: 10px;
backface-visibility: hidden;
}
<div class="flipcard h">
<div class="front" id="front">
This is the front side
</div>
<div class="back" id="back">
This is the back side
</div>
</div>
<button onclick="myFunction()">Flip The Image</button>
Simplify DOM, simplify JS and optimize CSS.
This is the best way to make a spinning card:
var card = document.querySelector('.card');
card.addEventListener( 'click', function() {
card.classList.toggle('is-flipped');
});
body { font-family: sans-serif; }
.card {
position: relative;
cursor: pointer;
transform-style: preserve-3d;
transform-origin: center right;
transition: transform 1s;
width: 200px;
height: 260px;
border: 1px solid #CCC;
margin: 40px 0;
perspective: 600px;
}
.card.is-flipped {
transform: rotateX(-180deg);
}
.card__face {
position: absolute;
width: 100%;
height: 100%;
line-height: 260px;
color: white;
text-align: center;
font-weight: bold;
font-size: 40px;
backface-visibility: hidden;
}
.card__face--front {
background: red;
}
.card__face--back {
background: blue;
transform: rotateX(180deg);
}
<div class="card">
<div class="card__face card__face--front">front</div>
<div class="card__face card__face--back">back</div>
</div>
You can do something like this:
$('#btnClick').click(function() {
$('.flip-container').toggleClass("flipped");
});
.flip-container.flipped .flipper {
-webkit-transform: rotateX(180deg);
-moz-transform: rotateX(180deg);
-o-transform: rotateX(180deg);
transform: rotateX(180deg);
position: relative;
}
.flip-container,
.front,
.back {
width: 200px;
height: 200px;
}
.flip-container {
-webkit-perspective: 1000;
-moz-perspective: 1000;
-o-perspective: 1000;
perspective: 500;
cursor: pointer;
top: 0;
width: 200px;
height: 200px;
}
.flip-container .back {
transform: rotateX(-180deg);
background-color: #000;
}
.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;
width: 200px;
height: 200px;
display: block;
}
.flip-container .front,
.flip-container .back {
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
transition: all 0.6s ease-in;
color: white;
background-color: #000;
padding: 10px;
backface-visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="flip-container">
<div class="flipper">
<div class="front">
<p>This is the front side </p>
</div>
<div class="back">
<p> This is the back side </p>
</div>
</div>
</div>
<button id="btnClick">Flip The Image</button>
I wanna create brochure which open to the left and the right when someone hover over it.
I use transform-origin: 0% and transform: rotateY(-180deg) for the left site of the brochure to open to the left site (Card red and blue). For the right side I use of course transform-origin: 100% and transform: rotateY(180deg) to open to the right site (Card green).
But the actual behavior of the right side is, that it applies transform-origin: 0% and rotates behind the left site of the brochure (Thats why you can't see it, but its there).
I can't understand why transform-origin: 100% don't take affect.
here is the code: https://jsfiddle.net/eL6q3hp4/2/
.book-container {
height: 350px;
width: 250px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
perspective: 1000px;
}
.book-part {
height: auto;
width: auto;
position: absolute;
transform-style: preserve-3d;
top: 0;
left: 0;
}
.book-part > .card {
height: 350px;
width: 250px;
position: absolute;
transform-style: preserve-3d;
backface-visibility: hidden;
}
/* RIGHT SITE */
.right-part {
transform-origin: 0%;
}
.right-card {
transform: rotateY(-180deg);
}
.book-container:hover .right-part {
transform: rotateY(180deg);
transition: 0.7s;
transition-delay: 0.3s;
}
/* LEFT SITE */
.left-part {
transform-origin: 100%;
}
.left-card {
transform: rotateY(180deg);
}
.book-container:hover .left-part {
transform: rotateY(-180deg);
transition: 0.7s;
}
.middle-card {
background-color: blue;
}
.right-card {
background-color: green;
}
.left-card {
background-color: red;
}
.front-card {
background-color: yellow;
}
<div class="book-container">
<div class="book-part middle-part">
<div class="card middle-card"></div>
</div>
<div class="book-part right-part">
<div class="card right-card"></div>
</div>
<div class="book-part left-part">
<div class="card left-card"></div>
<div class="card front-card"></div>
</div>
</div>
Remove absolute position from .book-part and invert the rotation values. You can also add a front card to the right block
I also added transition to the closing effect:
.book-container {
height: 350px;
width: 250px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
perspective: 1000px;
}
.book-part {
transform-style: preserve-3d;
}
.book-part>.card {
height: 350px;
width: 250px;
position: absolute;
transform-style: preserve-3d;
backface-visibility: hidden;
}
/* RIGHT SITE */
.right-part {
transform-origin: 0%;
transition: 0.7s;
}
.right-card {
transform: rotateY(180deg);
}
.book-container:hover .right-part {
transform: rotateY(-180deg);
transition-delay: 0.3s;
}
/* LEFT SITE */
.left-part {
transform-origin: 100%;
transition: 0.7s;
transition-delay: 0.3s;
}
.left-card {
transform: rotateY(-180deg);
}
.book-container:hover .left-part {
transform: rotateY(180deg);
transition-delay: 0s;
}
<div class="book-container">
<div class="book-part middle-part">
<div class="card middle-card" style="background:blue"></div>
</div>
<div class="book-part right-part">
<img class="card right-card" style="background:green">
<img class="card front-card" style="background:pink;">
</div>
<div class="book-part left-part">
<img class="card left-card" style="background:red">
<img class="card front-card" style="background:yellow">
</div>
</div>
You can also simplify your code like below:
.book-container {
height: 350px;
width: 250px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
perspective: 1000px;
background:blue;
}
.book-container > div{
transform-style: preserve-3d;
}
.book-container > div:before,
.book-container > div:after{
content:"";
height: 350px;
width:100%;
position: absolute;
transform-style: preserve-3d;
backface-visibility: hidden;
background:yellow;
}
/* RIGHT SITE */
.right-part {
transform-origin: 0%;
transition: 0.7s;
}
.book-container .right-part:before {
transform: rotateY(180deg);
background:green;
}
.book-container:hover .right-part {
transform: rotateY(-180deg);
transition-delay: 0.3s;
}
/* LEFT SITE */
.left-part {
transform-origin: 100%;
transition: 0.7s;
transition-delay: 0.3s;
}
.book-container .left-part:before {
transform: rotateY(180deg);
background:red;
}
.book-container:hover .left-part {
transform: rotateY(180deg);
transition-delay: 0s;
}
<div class="book-container">
<div class="right-part">
</div>
<div class="left-part">
</div>
</div>
I don't know if in the original situation you work with dynamic sizes (in which case this solution would not apply), but you can use a pixel value for transform-origin to make it work:
.book-container {
height: 350px;
width: 250px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-perspective: 1000px;
-moz-perspective: 1000px;
perspective: 1000px;
}
.book-part {
height: auto;
width: auto;
position: absolute;
transform-style: preserve-3d;
top: 0;
left: 0;
}
.book-part > .card {
height: 350px;
width: 250px;
position: absolute;
transform-style: preserve-3d;
backface-visibility: hidden;
}
/* RIGHT SITE */
.right-part {
transform-origin: 250px;
}
.right-card {
transform: rotateY(180deg);
}
.book-container:hover .right-part {
transform: rotateY(180deg);
transition: 0.7s;
transition-delay: 0.3s;
}
/* LEFT SITE */
.left-part {
transform-origin: 0%;
}
.left-card {
transform: rotateY(-180deg);
}
.book-container:hover .left-part {
transform: rotateY(-180deg);
transition: 0.7s;
}
.middle-card {
background-color: blue;
}
.right-card {
background-color: green;
}
.left-card {
background-color: red;
}
.front-card {
background-color: yellow;
}
<div class="book-container">
<div class="book-part middle-part">
<div class="card middle-card"></div>
</div>
<div class="book-part right-part">
<div class="card right-card"></div>
</div>
<div class="book-part left-part">
<div class="card left-card"></div>
<div class="card front-card"></div>
</div>
</div>
I have a parent div with a class of .card and it has to children div, that rotates in opposite directions when their parent is hovered over to create a flipping card. If you hover over it and wait until the transition finishes it works fine, however if you hover over it then move the mouse of before the animation finishes the div with a class of .front rotates in the opposite direction, why and is there a way to fix this? In addition if you move the mouse on and off multiple times both children start turning at different times even though they have the same trigger- why?
https://jsfiddle.net/8pktgqpu/15/
.card,.front,.back{
width: 100px;
height: 160px;
margin: 1px;
}
.card{
position: relative;
}
.front{
background-color: red;
transform: perspective(400px) rotatey(0deg);
backface-visibility: hidden;
transition: transform 1s ease-in-out 0s;
}
.back{
backface-visibility: hidden;
transform: perspective(400px) rotatey(180deg);
background-color: blue;
transition: transform 1s ease-in-out 0s;
position: absolute;
top: 0;
}
.card:hover .front{
transform: rotatey(-180deg);
}
.card:hover .back{
transform: rotatey(0deg);
}
Add a div and use perspective and transform-style: preserve-3d; to get it
below an example
.flip {
width: 300px;
height: 500px;
perspective: 1000px;
}
.flip_box {
width: 300px;
height: 500px;
position: relative;
transition: all 0.4s linear;
-webkit-transition: all 0.4s linear;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d
}
.front, .back {
position: absolute;
width: 300px;
height: 500px;
top: 0px;
left: 0px;
border: 1px solid #666;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.front {
color: red;
font-size: 16px;
}
.back {
color: blue;
font-size: 18px;
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
}
.flip:hover .flip_box {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
}
<div class="flip">
<div class="flip_box">
<div class="front">
Hello
</div>
<div class="back">
Bye
</div>
</div>
</div>
Try this...
.card-container {
perspective: 1000px;
}
.card-container:hover .card, .card-container.hover .card {
transform: rotateY(180deg);
}
.card-container, .front, .back {
width: 100px;
height: 160px;
margin: 1px;
}
.card {
transition: 1s ease-in-out 0s;
transform-style: preserve-3d;
position: relative;
}
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front {
z-index: 2;
transform: rotateY(0deg);
background-color: red;
}
.back {
transform: rotateY(180deg);
background-color: blue;
}
<div class="card-container">
<div class="card">
<div class="front">
front
</div>
<div class="back">
back
</div>
</div>
</div>
Why for the following HTML:
<div class="container">
<div class="bottom">
<div class="face"></div>
</div>
</div>
And CSS:
.container {
width: 300px;
height: 300px;
position: relative;
transform: perspective(900px);
transform-style: preserve-3d;
animation: rot 8s infinite linear;
}
.bottom {
width: 200px;
height: 200px;
background-color: blue;
position: absolute;
top: 15%;
left: 15%;
opacity: 1;
}
.face {
width: 100px;
height: 200px;
background-color: red;
position: absolute;
left: 0px;
top: 0px;
transform-origin: 0% 0%;
transform: rotateY(60deg);
}
A blue square doesn't cover the red rectangle when it turns back (backface-visibility doesn't help)? At the same time when .bottom and .face are not in a parent-child relationship everything works as expected.
See plunker
Note: works in Chrome. In Firefox the first example doesn't work. In IE both of them.
Most of the CSS propertis inherit.
transform-style is an exception
setting
.bottom {
transform-style: preserve-3d;
}
or
.bottom {
transform-style: inherit;
}
will solve the problem
demo
I have a fiddle http://jsfiddle.net/nLhgT/
I followed the instructions here http://davidwalsh.name/css-flip and http://desandro.github.io/3dtransforms/docs/card-flip.html When I flip the card, only the front side is being shown (flipped). I can't seem to get the backface to show. I've read similar questions on stackoverflow saying the backface must be rotated first. It is indeed rotated initially in my example.
HTML
<ul>
<li>
<div class="container">
<div class="card">
<div class="front">
front
</div>
<div class="back">
back
</div>
</div>
</div>
</li>
</ul>
CSS
li {
width: 300px;
height: 260px;
position: relative;
perspective: 800px;
list-style-type: none;
}
.card {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
-webkit-transition-duration: 400ms;
transition-duration: 400ms;
}
.card div {
display: block;
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.card .front {
background: red;
}
.card .back {
background: blue;
-webkit-transform: rotateY( 180deg );
transform: rotateY(180deg);
}
.card.flip {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}
JS
$(document.body).on('click', '.card', function() {
console.log("CLICK");
document.querySelector('.card').classList.toggle("flip");
});
The only difference in my example is that the card is within an unordered list. I intend to make a list of these cards. But I don't think that should affect things.
So the main problem is that preserve-3d isn't supported by IE. Huge bummer, but not much that can be done about it. Therefore, you should be applying the transform to each child element, not the entire card.
The best way I've found of making a card flip is as follows:
Transform each face. The front should default to 0, the back to 180. When flipped, they should be 180 and 360 respectively.
Apply a z-index to them. The visible face should have something like 10, while the hidden one has 0. This ensures that the right one is in front at all times (even in browsers that don't support transformations)
Here is my update to your Fiddle showing a working card flip.
Here you go...
Demo Fiddle
HTML:
<ul>
<li>
<div class="container" id="flip-toggle">
<div class="card">
<div class="front">front</div>
<div class="back">back</div>
</div>
</div>
</li>
</ul>
CSS:
li {
width: 300px;
height: 260px;
position: relative;
perspective: 800px;
list-style-type: none;
}
.container {
-webkit-perspective: 1000;
-moz-perspective: 1000;
perspective: 1000;
border: 1px solid #ccc;
}
#flip-toggle.flip .card {
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
filter: FlipH;
-ms-filter:"FlipH";
}
.container, .front, .back {
width: 300px;
height: 260px;
}
.card {
-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;
width: 100%;
height: 100%;
}
.front, .back {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front {
background: red;
z-index: 2;
}
.back {
background: blue;
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
}
JS:
$(document.body).on('click', '.card', function () {
console.log("CLICK");
document.querySelector('#flip-toggle').classList.toggle('flip');
});