I have a flip animation on this page https://muttcase.com.au/products/call-my-mum-shes-lost-without-me it works perfectly in all browsers except safari..I've tried prefixes but I'm lost. the css im using is..
/* entire container, keeps perspective */
.product-single__photos {
perspective: 1000px;
}
.product-single__photos, .front, .back {
width: 320px;
height: 420px;
}
/* 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);
}
.flippy .flipper, .product-single__photos.flippy .flipper, .product-
single__photos.flip .flipper {
transform: rotateY(180deg);
}
Couple of issues I resolved to get it to work well in Safari:
Your .front element is empty. Check your HTML and, I assume you want this, put the #ProductImageWrapper... element inside of .front. This could be due to a syntax issue or an unclosed <div> tag in your HTML.
You don't need transform: rotateY(180deg) on both the .front and .back elements. Your code sample doesn't show it this way, but the code on the site you linked does.
The "Flip Tag" button then falls behind the elements because all of the elements in the preceding sibling are now (as you intended) position: absolute. Go ahead and post another question if you have issues with that one.
Related
I have a flip animation were I use perspective, I have a simple card that flips when hovered. From my understanding the perspective property and the transform property perspective() are the same except perspective is applied to the parent and is rendered on its children and the perspective() is applied directly to an element you want to have perspective, is this correct? I used the perspective property at first then realized I could simplify my code slightly by using perspective() so I changed it. With perspective() if you hover over the card the animation works but if you move the mouse off and back on before the animation finishes at the very beginning of the animation you get some weird results, the back of the card will show through the front and the card will stretch across the screen, all this weird behavior stops when I give the card a parent with a perspective property and delete the perspective(), so is this a browser error or am I not understanding the differences correctly or is there some other property I need to use with perspective() that I'm not aware off?
two versions of css with results
perspective: 1000px;
https://fiddle.jshell.net/rqzwoguw/28/
transform: perspective(1000px);
https://fiddle.jshell.net/rqzwoguw/29/ // move mouse on and off at the beginning or the middle point of the transition.
Keep the pespective constant, don't change it on hover.
Just add to .card: (no rotation, but the same pespective that you are setting on hover)
transform: perspective(1000px) rotateY(0deg);
.front,
.back,
.card {
width: 100px;
height: 170px;
border-radius: 10px;
text-align: center;
}
.card {
position: relative;
transition: transform 1s ease-in-out 0s;
transform-style: preserve-3d;
transform-origin: right;
transform: perspective(1000px) rotateY(0deg);
}
.card:hover {
transform: perspective(1000px) rotateY(180deg);
}
.front {
background-color: red;
}
.back {
background-color: blue;
transform: rotateY(180deg);
position: absolute;
top: 0px;
z-index: -1;
}
<div class="card">
<div class="front">
FRONT
</div>
<div class="back">
BACK
</div>
</div>
I'm trying to create a div "flipcard" element that contains different sized content on the front and back.
The HTML:
<div class="flipcard">
<div class="face front">Front</div>
<div class="face back">Back ... put some long text here ... </div>
</div>
The Javascript just adds and removes a "flipped" class:
$('.flipcard').click(function(e) {
var $card = $(this);
if ($card.hasClass("flipped")) $card.removeClass('flipped');
else $card.addClass('flipped');
});
All the magic happens in the CSS:
.flipcard {
margin: 1em auto;
width: 80%;
/* I don't want to set the height because
we don't know the size of the content */
border: solid 1em white;
border-radius: 0.5em;
font-family: Georgia;
-webkit-perspective: 800;
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
cursor: pointer;
}
.flipcard:hover {
box-shadow: 0 0 1em black;
}
.flipcard.flipped {
-webkit-transform: rotatey(-180deg);
}
.flipcard .face {
padding: 1em;
text-align: center;
-webkit-backface-visibility: hidden;
}
.flipcard .front {
background: #220000;
color: white;
}
.flipcard .back {
background: #66eeff;
color: black;
-webkit-transform: rotateY(180deg);
}
JSFiddle: http://jsfiddle.net/luken/qdBEV/
As you can see, the content from the front is interfering with the back, and they both stretch the flipcard to the combined height. I'd like the front to show with the proper height of its content and the back to show with the proper height of its content. I've tried making the faces position: absolute and making them go from display: none to display: block on each flip... but nothing works quite right.
Any ideas?
Add proper display:none; and display:block;
Demo: http://jsfiddle.net/qdBEV/3/
CSS:
body {
background: #bbb;
}
.flipcard {
perspective: 800;
-moz-perspective: 800;
-webkit-perspective: 800;
margin: 1em auto;
width: 80%;
border: solid 1em white;
border-radius: 0.5em;
font-family: Georgia;
transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
transition: 0.5s;
-moz-transition: 0.5s;
-webkit-transition: 0.5s;
cursor: pointer;
}
.flipcard:hover {
box-shadow: 0 0 1em black;
}
.flipcard.flipped {
transform: rotatey(-180deg);
-moz-transform: rotatey(-180deg);
-webkit-transform: rotatey(-180deg);
}
.flipcard .face {
padding: 1em;
text-align: center;
backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.flipcard .front {
background: #220000;
color: white;
display: block; /* added to fix the problem */
}
.flipcard.flipped .front {
display:none; /* added to fix the problem */
}
.flipcard .back {
background: #66eeff;
color: black;
transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
display:none; /* added to fix the problem */
}
.flipcard.flipped .back {
display:block; /* added to fix the problem */
}
I had to implement this problem at work and maybe this post will help others, so here is what I came up with (see jsfiddle). First off, the requirements in my case were a bit tighter than a flipping div with different height faces. Additionally:
There is content below the flip card that has to shift up and down smoothly (e.g. another CSS transiton) while the card flips in order to accommodate for the different heights of the faces.
The content on the faces as well as what is above and below the flip card has to adhere to the responsive design of the page, in other words the card cannot have any fixed CSS dimensions nor absolute positioning.
Support for all major browsers, but only latest versions.
HTML is the same as in the question - one "card" with two "faces":
<div class="flipcard">
<div class="flipcard-front">
<h1>Front</h1>
<p>some shorter content</p>
</div>
<div class="flipcard-back">
<h1>Back</h1>
<p>some long content</p>
...
</div>
</div>
CSS (looks daunting, but actually just a couple of line of LESS):
.flipcard {
position: relative;
height: auto;
min-height: 0px;
/* Flip card styles: WebKit, FF, Opera */
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
-webkit-transition: min-height 1s ease-out 0s, -webkit-transform 1s ease-out 0.5s;
-moz-transition: min-height 1s ease-out 0s, -moz-transform 1s ease-out 0.5s;
-o-transition: min-height 1s ease-out 0s, -o-transform 1s ease-out 0.5s;
/* only height adjustment for IE here */
-ms-transition: min-height 1s ease-out 0s;
}
/* The class that flips the card: WebKit, FF, Opera */
.flipcard.card-flipped {
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
}
.flipcard .flipcard-front,
.flipcard .flipcard-back {
top: 0;
left: 0;
width: 100%;
/* backface: all browsers */
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
/* Flip card styles: IE 10,11 */
-ms-perspective: 800px;
-ms-transform-style: flat;
-ms-transition: -ms-transform 1s ease-out 0.5s;
}
.flipcard .flipcard-front {
position: relative;
display: inline-block;
-webkit-transform: rotateY(0deg);
-ms-transform: rotateY(0deg);
-o-transform: rotateY(0deg);
transform: rotateY(0deg);
}
.flipcard .flipcard-back {
position: absolute;
display: none;
-ms-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
transform: rotateY(180deg);
/* webkit bug: https://bugs.webkit.org/show_bug.cgi?id=54371,
You need this fix if you have any input tags on your back face */
-webkit-transform: rotateY(180deg) translateZ(1px);
}
/* The 2 classes that flip the faces instead of the card: IE 10,11 */
.flipcard .flipcard-front.ms-front-flipped {
-ms-transform: rotateY(180deg);
}
.flipcard .flipcard-back.ms-back-flipped {
-ms-transform: rotateY(0deg);
}
Notes: Unfortunately the latest versions of IE still handle CSS rotations differently than all the others in that it expects each face to be flipped individually instead of flipping the card that contains them. Although webKit browsers, FF and Opera seem to "understand" this, I wanted maximal backward compatibility for those browsers and hence all this ugly browser prefix clutter (google for David Walsh's great post on flip cards). Secondly, I wanted older browsers to at least show the right content and so the invisible (back) face had to be display: none while the visible face had to be display: block-inline to avoid collapsed margins with content above and below the card. Thirdly, the shifting of the content following the flip card can be achieved by controlling the cards min-height property while leaving it's height: auto (credit). Running the shift a bit ahead of the rotation makes it really smooth.
Finally, the Javascript:
function flipCard() {
var card = $('.flipcard');
var front = $('.flipcard-front');
var back = $('.flipcard-back');
var tallerHight = Math.max(front.height(), back.height()) + 'px';
// visible/invisible *before* the card is flipped ;D
var visible = front.hasClass('ms-front-flipped') ? back : front;
var invisible = front.hasClass('ms-front-flipped') ? front : back;
var hasTransitioned = false;
var onTransitionEnded = function () {
hasTransitioned = true;
card.css({
'min-height': '0px'
});
visible.css({
display: 'none',
});
// setting focus is important for keyboard users who might otherwise
// interact with the back of the card once it is flipped.
invisible.css({
position: 'relative',
display: 'inline-block',
}).find('button:first-child,a:first-child').focus();
}
// this is bootstrap support, but you can listen to the browser-specific
// events directly as well
card.one($.support.transition.end, onTransitionEnded);
// for browsers that do not support transitions, like IE9
setTimeout(function() {
if (!hasTransitioned) {
onTransitionEnded.apply();
}
}, 2000);
invisible.css({
position: 'absolute',
display: 'inline-block'
});
card.css('min-height', tallerHight);
// the IE way: flip each face of the card
front.toggleClass('ms-front-flipped');
back.toggleClass('ms-back-flipped');
// the webkit/FF way: flip the card
card.toggleClass('card-flipped');
}
This applies the classes for flipping the card/faces. During the transition, the back face has a position: absolute so it is visible while the card is turned. At the same time, the card's height is transitioned. At the end of the transition, the visible face returns to is position: relative and the card's height is derestricted leaving back a responsive page.
Hope this helps - sorry for this lengthy post, it's my first :)
When I use a webkit 3d transform on hover, only the top 50% of the hover area works, while the bottom 50% is unstable. I'm currently testing on Chrome (31.0.1650.63). Is it a bug? Is there any workaround?
Try to place your mouse on the top of the div and slowly bring it to the bottom.
HTML
<div class="hoverArea"></div>
<div class="flip">
<div class="front">front</div>
<div class="back">back</div>
</div>
CSS
.hoverArea, .flip, .front, .back {
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.hoverArea {
z-index: 10;
}
.flip {
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.5s;
-webkit-perspective: 800;
z-index: 9;
}
.front {
background-color: #f00;
-webkit-backface-visibility: hidden ;
}
.back {
background-color: #f0f;
-webkit-transform: rotatex(-180deg);
-webkit-backface-visibility: hidden ;
}
.hoverArea:hover + .flip {
-webkit-transform: rotatex(-180deg);
}
http://jsfiddle.net/4P53y/
You can fix it by removing the .hoverArea element and instead apply the :hover event on the .flip element.
.flip:hover {
-webkit-transform: rotatex(-180deg);
}
Demo
If you want to still use the .hoverArea element then you can use transform:translateZ(1px); on .hoverArea to make it function correctly. It makes the browser render the element more carefully
.hoverArea {
z-index: 10;
-webkit-transform:translateZ(1px);
}
Demo
I am following a CSS3 tutorial to offer cardflip functionality.
When the user hovers or touches the image, I wish for the image to flip over and display a 2nd image.
So far, I have:
/* entire container, keeps perspective */
.flip-container {
perspective: 1000;
}
/* flip the pane when hovered */
.flip-container:hover .flipper {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
}
.flip-container, .front, .back {
width: 300px;
height: 300px;
}
/* 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;
-webkit-backface-visibility:hidden; /* Chrome and Safari */
-moz-backface-visibility:hidden; /* Firefox */
-ms-backface-visibility:hidden; /* Internet Explorer */
position: absolute;
top: 0;
left: 0;
}
/* front pane, placed above back */
.front {
z-index: 2;
}
/* back, initially hidden pane */
.back {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-o-transform: rotateY(180deg);
}
http://jsfiddle.net/jP39d/
The problem is that the front image shows the image still despite me setting backface-visibility: hidden;, but reversed. Image 2 is nowhere to be seen!
Add -webkit-transform-style: preserve-3d; besides transform-style: preserve-3d;. It should work now.
And I guess you want to use -webkit-perspective too because you only used perspective.
So, it's only a prefix issue. Propably you should add -moz and -o too if you want to support them.
I am performing a CSS transform: rotate on a parent, yet would like to be able to negate this effect on some of the children - is it possible without using the reverse rotation?
Reverse rotation does work, but it affects the position of the element, and it may have a negative performance impact (?). In any case, it doesn't look like a clean solution.
I tried the "transform: none" suggestion from this question prevent children from inheriting transformation css3, yet it simply doesn't work - please see the fiddle here: http://jsfiddle.net/NPC42/XSHmJ/
May be you have to write like this:
.child {
position: absolute;
top: 30px;
left: 50px;
background-color: green;
width: 70px;
height: 50px;
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
transform: rotate(-30deg);
}
Check this for more http://jsfiddle.net/XSHmJ/1/
Updated:
You can use:after & :before psuedo class for this.
check this http://jsfiddle.net/XSHmJ/4/
I believe that you are going to need to fake it using a second child, the specification does not seem to allow for the behavior you would like, and I can understand why the position of a child element has to be affected by a transform to its parent.
This isn't the most elegant of solutions, but I think you're trying to do something that the specification is never going to allow. Take a look at the following fiddle for my solution:
.parent {
position: relative;
width: 200px;
height: 150px;
margin: 70px;
}
.child1 {
background-color: yellow;
width: 200px;
height: 150px;
-webkit-transform: rotate(30deg);
-moz-transform: rotate(30deg);
-o-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
.child2 {
position: absolute;
top: 30px;
left: 50px;
background-color: green;
width: 70px;
height: 50px;
}
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
If you want to apply transforming effects on a parent without affecting its children, you can simply animate a parent's pseudo-element like this:
.parent {
display: inline-block;
position: relative;
}
.parent::before {
content: "";
background: #fab;
/* positioning / sizing */
position: absolute;
left: 0;
top: 0;
/*
be aware that the parent class have to be "position: relative"
in order to get the width/height's 100% working for the parent's width/height.
*/
width: 100%;
height: 100%;
/* z-index is important to get the pseudo element to the background (behind the content of parent)! */
z-index: -1;
transition: 0.5s ease;
/* transform before hovering */
transform: rotate(30deg) scale(1.5);
}
.parent:hover::before {
/* transform after hovering */
transform: rotate(90deg) scale(1);
}
This actually worked for me. JSFiddle