Safari CSS issue with overlayed animations - css

I have a simple card flip animation which works well on the browsers I've tested.
However there is an issue on Safari when this card flip animation happens on top of another div which is also being animated. For some reason on Safari when the card flips it kind of disappears behind the "background div". I thought that maybe it's a z-index issue but from what I tried it is not.
To make the example simple the background div is grey. The idea is to have a glowing effect in the background.
Below is the example of the code that I have, I've tested this on Chrome, Firefox and Edge it's working fine, however on Safari when the card is flipped it disappears.
$(document).ready(function() {
$('button').click(function() {
$('.wrapper').toggleClass('flip');
});
});
.perspective {
perspective: 1000px;
margin: 50px;
position: relative;
width: 175px;
height: 250px;
}
.some-bg {
background-color: #ccc;
background-position: center;
width: 100%;
height: 100%;
position: absolute;
animation: test-bg-animation 1s infinite linear;
}
#keyframes test-bg-animation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.wrapper {
width: 125px;
height: 175px;
border: 1px solid blue;
position: absolute;
transform-style: preserve-3d;
transition: all 250ms;
top: 35px;
left: 25px;
}
.wrapper.flip {
transform: rotateY(180deg);
}
.card-face {
width: 100%;
height: 100%;
position: absolute;
-webkit-backface-visibility: hidden;
}
.back {
background-color: tomato;
}
.front {
background-color: #bada55;
transform: rotateY(180deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="perspective">
<div class="some-bg"></div>
<div class="wrapper">
<div class="card-face front">Front</div>
<div class="card-face back">Back</div>
</div>
</div>
<button>Flip Me!</button>

You can fix this by nesting the .some-bg and the .wrapper div into absolute positioned divs with a relative positioned parent.
See this fiddle for an example:
https://jsfiddle.net/voLzv68w/

Related

Transform: scale() not transforming from center

When I hover, it scales perfectly but the logo moves up a little bit. I tried transform-origin: center (even though that is the default) and nothing changed.
HTML
<div class="portfolio-projects">
<div class="project">
<img src="#" alt="">
</div>
</div>
CSS
portfolio-projects {
display: grid;
grid-gap: 50px;
margin: 50px 0;
max-width: 1050px;
.project {
position: relative;
cursor: pointer;
background-color: $gray;
max-width: 500px;
height: 325px;
overflow: hidden;
}
img {
position: absolute;
top: 35%;
left: 50%;
transform: translate(-50%,-35%) scale(.8);
transition: .2s;
}
.project:hover {
img {
transform: translate(-50%,-50%) scale(.9);
}
}
Wow. So I just needed to change it to this
.project:hover {
img {
transform: translate(-50%,-35%) scale(.9);
}
}
I forgot to adjust the hover after adjust the original value.

CSS animation - prevent 'sliding' on rotate3d

I'm trying to create the effect of an opening door in css.
The issue I'm having is that the part which rotates also slides along the y axis. A door has a fixed rotation point, which is not really working here.
How can I prevent this sliding and ensure that the right part of the div .mover stays fixed to the right of the div .door?
.door {
background-color: blue;
width: 100px;
height:100px;
margin-left: 300px;
display: block;
}
.mover {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
transition: all 1s ease;
}
.door:hover .mover {
transform-origin: 100% 40%;
transform: rotate3d(0,1,0,180deg);
}
<div class="door">
<div class="mover">a</div>
</div>
Move the transform-origin to the base .mover selector, instead of the .door:hover .mover selector. Like this:
.door {
background-color: blue;
width: 100px;
height:100px;
margin-left: 300px;
display: block;
}
.mover {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
transition: all 1s ease;
transform-origin: 100% 40%;
}
.door:hover .mover {
transform: rotate3d(0,1,0,180deg);
}
<div class="door">
<div class="mover">a</div>
</div>

CSS animate a div with absolute positioning from left 0 to right 0

Consider this sample.
http://jsfiddle.net/dfabulich/ncbzz5zu/3/
<html>
<body>
<style>
.container {
position: relative;
width: 80%;
height: 100px;
border: 1px solid black;
}
#keyframes slide {
from { background-color: red; left: 0; }
to { background-color: blue; right: 0; }
}
.animated {
position: absolute;
width: 20%;
height: 100%;
top: 0;
background-color: red;
animation-duration: 3s;
animation-name: slide;
animation-iteration-count: infinite;
}
</style>
<div class=container>
<div class=animated>
</div></div>
Expected: The red rectangle should smoothly animate from left to right as the color changes from red to blue.
Actual: In Chrome/Firefox, the red rectangle slowly changes color to purple, then teleports from left to right without animating, and then slowly changes from purple to blue. In Safari, the rectangle appears on the right and never moves from there, while animating from red to blue.
Why is this happening? How can I fix it? (I need to fix it in CSS… no JS, no jQuery.)
You need to animate one property or the other. You can just animate left and either use left: calc(100% - elemWidth) (where elemWidth is the width of the element) or left: 100%; transform: translateX(-100%); if the width of the element is unknown.
Also need to animate background color.
.container {
position: relative;
width: 80%;
height: 100px;
border: 1px solid black;
}
.animated {
position: absolute;
width: 20%;
height: 100%;
top: 0;
background-color: red;
animation: 3s linear 0s slide infinite;
}
#keyframes slide {
from { left: 0; }
to {
left: 100%;
transform: translateX(-100%);
background: blue;
}
}
<div class=container>
<div class=animated>
</div></div>
The problem is that you start animating property left, but then replace it with right in the end of animation, that's why it jumps. You should keep animating the same property to get the step by step animation progression.
.container {
position: relative;
width: 80%;
height: 100px;
border: 1px solid black;
}
#keyframes slide {
from { background-color: red; left: 0; }
to { background-color: blue; left: 80%; }
}
.animated {
position: absolute;
width: 20%;
height: 100%;
top: 0;
background-color: red;
animation-duration: 3s;
animation-name: slide;
animation-iteration-count: infinite;
}
<div class="container"><div class="animated"></div></div>
#keyframes slide {
from { left: 0;}
to { left: 80%; } // edit: actually endpoint should point to left:100% minus width of the element so in your case 100%-20% = 80%. In case of width of the element in px use CSS calc like: left: calc(100% - ##px);
}
Simply when you used right you told transition to change totally different property. That is why you were jumping between left: 0 what is left side of your screen to right: 0 what is right edge of your screen.
<html>
<body>
<style>
.container {
position: relative;
width: 80%;
height: 100px;
border: 1px solid black;
}
#keyframes slide {
0% { background-color: red; left: 0; }
100% { background-color: blue; left: 100%; margin-left: -20%; }
}
.animated {
position: absolute;
width: 20%;
height: 100%;
top: 0;
background-color: red;
animation-duration: 3s;
animation-name: slide;
animation-iteration-count: infinite;
}
</style>
<div class=container>
<div class=animated>
</div></div>
see this snippet...
This is what it should look like:
http://jsfiddle.net/ncbzz5zu/11/
And this is the fix for it:
#keyframes slide {
from { background-color: red;
left:0%;}
to { background-color:blue;
left:80%;}
}
Basically, the animation didnt know what to do since you specified the initial left property but not the target value. It animated from left:0 to left:initial. Right fulfills a similar function to left but its still another property.

Flip a 3D card with CSS

I'm trying to make a 3D card flipping effect with CSS like this.
The difference is that I want to use only CSS to implement it.
Here is the code I tried:
/*** LESS: ***/
.card-container {
position: relative;
height: 12rem;
width: 9rem;
perspective: 30rem;
.card {
position: absolute;
width: 100%;
height: 100%;
div {
position: absolute;
height: 100%;
width: 100%;
}
.front {
background-color: #66ccff;
}
.back {
background-color: #dd8800;
backface-visibility: hidden;
transition: transform 1s;
&:hover {
transform: rotateY(180deg);
}
}
}
}
HTML:
<div class="card-container">
<div class="card">
<div class="front"><span>Front</span></div>
<div class="back"><span>Back</span></div>
</div>
</div>
The issue is that the card doesn't flip, it snaps from back to front like this:
Is it possible to implement this 3d card flip on hover effect using only CSS?
I simplified the code to make it shorter and make the 3d card flip on hover. The card flips on the Y axis from the front face to the back face this is what it looks like:
Here is an example of a simple CSS only flipping card the flip animation is launched on hover :
.card {
position: relative;
width: 50vh;
height: 80vh;
perspective: 500px;
margin: 10vh auto 50vh;
}
.front,
.back {
position: absolute;
width: 100%;
height: 100%;
transition: transform 1s;
backface-visibility: hidden;
transform-style: preserve-3d;
}
.front {
background-color: #66ccff;
}
.back {
background-color: #dd8800;
transform: rotateY(180deg);
}
.card:hover .front {
transform: rotateY(180deg);
}
.card:hover .back {
transform: rotateY(360deg);
}
<div class="card">
<div class="front"><span>Front</span></div>
<div class="back"><span>Back</span></div>
</div>
Note that you will need to add vendor prefixes depending on the browsers you want to support. See canIuse for 3d transforms and transitions.
This is what I changed in your code for the flip effect:
the front face wasn't rotated on th Y axis on hover
the hover effect was launched when the .back div was hovered. This can create flickering as that div is rotating and "disapears" at mid rotation. It's better to launch the animation when the static parent is hovered.
the first parent isn't really usefull so I removed it
yes it can be done using CSS only and you can do by using CSS3 animation property. Here is example of flipping card animation.
<div class="container text-center">
<div class="card-container">
<div class="card">
<div class="front">
<span class="fa fa-user"></span>
</div>
<div class="back">User</div>
</div>
</div>
The CSS
.card-container {
display: inline-block;
margin: 0 auto;
padding: 0 12px;
perspective: 900px;
text-align: center;
}
.card {
position: relative;
width: 100px;
height: 100px;
transition: all 0.6s ease;
transform-style: preserve-3d;
}
.front, .back {
position: absolute;
background: #FEC606;
top: 0;
left: 0;
width: 100px;
height: 100px;
border-radius: 5px;
color: white;
box-shadow: 0 27px 55px 0 rgba(0, 0, 0, 0.3), 0 17px 17px 0 rgba(0, 0, 0, 0.15);
backface-visibility: hidden;
}
.front {
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
}
.back {
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
}
.card-container:hover .card {
transform: rotateY(180deg);
}
.back {
transform: rotateY(180deg);
}
You can also read this article about CSS Flip Animation on Hover
You can also find demo and download source from the article.

Why does setting overflow:hidden; break the backface-visibility declaration?

I have a "flippable" modal dialogue consisting of two divs (front and back):
<div class="modal-dialogue">
<div class="modal-content">
<div class="front">
<h1>Front</h1>
</div>
<div class="back">
<h1>Back</h1>
</div>
</div>
</div>
Using CSS transform I flip the modal over to reveal the back by adding the "flipped" class to the modal-content with:
.modal-content.flipped {
-webkit-transform: rotateY(180deg);
}
This all works fine... except when I add the overflow:hidden; property to the modal-content. Suddenly, the back div is not visible and instead the backface of the front div becomes visible (even though it has backface-visibility set to hidden).
This seems very strange. Why would setting the overflow property change the backface-visibility in this way?
You can see it in action in this fiddle: https://jsfiddle.net/amxp02mx/ . It works fine, but if you comment out line 31 in the CSS, making the overflow:hidden, it is broken.
Can anyone explain why?
document.querySelector(".modal-content")
.addEventListener("click", function () {
this.classList.toggle("flipped");
});
.modal-dialogue {
z-index: 1050;
display: block;
width: 25rem;
min-height: 30rem;
margin-left: -12.5rem;
margin-top: -15rem;
position: fixed;
left: 50%;
top: 50%;
-webkit-perspective: 800px;
}
.modal-content {
width: 25rem;
min-height: 30rem;
position: relative;
background-color: transparent;
border-radius: 10px;
outline: none;
transition: 0.8s ease;
-webkit-transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1s;
margin: 5rem auto 0 auto;
/* With overflow:hidden; the back of the panel is
not visible and the backface-visibility:hidden
stops working. Why? */
overflow: hidden;
/* With overflow: visible; it works fine. */
overflow: inherit;
}
.modal-content div {
display: block;
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
color: white;
font-size: 140px;
font-weight: bold;
text-align: center;
overflow: hidden;
}
.modal-content .front {
background: red;
z-index:0;
}
.modal-content .back {
background: blue;
-webkit-transform: rotateY(180deg);
z-index:-1;
}
.modal-content.flipped {
-webkit-transform: rotateY(180deg);
}
<div class="modal-dialogue">
<div class="modal-content">
<div class="front">
<h1>Front</h1>
</div>
<div class="back">
<h1>Back</h1>
</div>
</div>
</div>
you can see the explanation here in the documentation:
https://drafts.csswg.org/css-transforms/#grouping-property-values
also your issue is easily fixed by adding
overflow:hidden;
to the .modal-content div rule
https://jsfiddle.net/amxp02mx/4/

Resources