I have created a flip board animation with CSS transitions, and it works fine in Chrome/Firefox/Edge, but in Safari it flickers a lot during the transition, but the final state is correct.
I thought it might be a problem with the z-index in the transitions, but when removing those the flickering is still there.
I have autoprefixer on so I don't think it's an issue with backface-visibility.
If you look at this codepen in both Chrome and Safari, you can see the how it's supposed to be in Chrome, and the flickering issue in Safari.
https://codepen.io/joel-udd/pen/QWpEQMM
<div class="board board-1">
<div class="row-1">
<div class="letter-wrapper">
<div class="behind-letter">
<div class="behind bottom"><span>F</span></div>
<div class="behind top">I</div>
</div>
<div class="letter">
<div class="flip front">H</div>
<div class="flip back"><span>I</span></div>
</div>
<div class="letter">
<div class="flip front">G</div>
<div class="flip back"><span>H</span></div>
</div>
<div class="letter">
<div class="flip front">F</div>
<div class="flip back"><span>G</span></div>
</div>
</div>
</div>
</div>
.board {
display: inline-block;
position: relative;
perspective: 1000px;
.letter-wrapper {
display: inline-block;
position: relative;
width: 11vw;
margin-left: 2px;
height: 14vw;
.flip, .behind {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
font-size: 14vw;
span {
display: inline-block;
transform: translateY(-50%);
}
}
.letter {
display: inline-block;
position: absolute;
top: 2px;
width: 100%;
height: 7vw;
transform: rotateX(0);
transform-style: preserve-3d;
transform-origin: bottom center;
.flip {
height: 100%;
backface-visibility: hidden;
&.back {
transform: rotateX(180deg);
}
}
&:nth-child(2) {
z-index: 10;
}
&:nth-child(3) {
z-index: 20;
}
&:nth-child(4) {
z-index: 30;
}
}
.behind-letter {
display: inline-block;
position: absolute;
width: 100%;
height: 100%;
z-index: 5;
.behind {
height: 50%;
&.bottom {
top: calc(50% + 2px);
}
}
}
}
&.active {
.row-1 {
.letter-wrapper {
.letter {
transform: rotateX(-180deg);
&:nth-child(2) {
z-index: 50;
transition: transform .5s .5s, z-index 0s .6s;
}
&:nth-child(3) {
z-index: 40;
transition: transform .5s .3s, z-index 0s .4s;
}
&:nth-child(4) {
transition: transform .5s .1s;
}
}
}
}
}
}
Thanks!
Related
I have a simple scaling animation applied to a circle using keyframes.
There is an unexpected and undesirable line that scales with the circle in Chrome Version 85.0.4183.102 (Official Build) (64-bit) and not in Firefox or Safari.
I cannot remove it - do you know how to? I have tried adding border: 0 to the various divs unsuccessfully.
#parent { overflow: hidden; background: #F0F4FF; height: 500px; width: 100%; position: relative; user-select: none; margin-block-end: 5rem; z-index: 3; }
.child { width: 100%; height: 100%; }
.child .inner { background: radial-gradient(circle at center, #D90368 20%, #F0F4FF 20%); }
.inner { position: relative; left: 0; top: 0; animation: circle 2s linear infinite; display: block; height:100%; width: 100%; content: " "; }
#keyframes circle { 0% { transform: scale(0.5) } 50% { transform: scale(1.2) } 80% { transform: scale(0.95) } 100% { transform: scale(1.0) } }
<div id='parent'>
<div class='child'>
<span class='inner'></span>
</div>
</div>
I have tried to search SO however I find a lot of similar line / scale / keyframe posts but these are intentional line animation posts.
I had the line to on Chrome. So I edited the code a bit, and the line was gone. Not sure what the problem was, just a different solution:
The html:
<div id="parent">
<div class="child">
<div class="inner"></div>
</div>
</div>
And the CSS
#parent {
overflow: hidden;
background: #f0f4ff;
height: 500px;
width: 100%;
position: relative;
user-select: none;
margin-block-end: 5rem;
z-index: 3;
}
.child {
width: 100%;
height: 100%;
position: relative;
}
.inner {
background-color: #d90368;
width: 10rem;
height: 10rem;
position: absolute;
left: calc(50% - 5rem);
top: calc(50% - 5rem);
animation: circle 2s linear infinite;
display: block;
content: " ";
border-radius: 50%;
}
#keyframes circle {
0% {
transform: scale(0.5);
}
50% {
transform: scale(1.2);
}
80% {
transform: scale(0.95);
}
100% {
transform: scale(1);
}
}
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>
This question already has answers here:
CSS transform doesn't work on inline elements
(2 answers)
Closed 3 years ago.
I have a jsfiddle here and animation named fromBottom is not working.
http://jsfiddle.net/8g5r2qcw/1/
html
<header class="header">
<div class="header__logo-box">
<img src="https://dtgxwmigmg3gc.cloudfront.net/imagery/assets/derivations/icon/256/256/true/eyJpZCI6ImE4OWEzMGU2YTg5NTViYjcxZWY1OTJiNDlkYjZjMTRhLmpwZyIsInN0b3JhZ2UiOiJwdWJsaWNfc3RvcmUifQ?signature=8735e0713b1bd34828e75056d2c51efc7ffc62c0167dcb80e7d66fe8550b9bc6" alt="Logo" class="header__logo">
</div>
<div class="header__text-box">
<h1 class="heading-primary">
<span class="heading-primary--main">Outdoors</span>
<span class="heading-primary--sub">is where life happens</span>
</h1>
Discover our tours
</div>
</header>
relevant css
/* this animation not working */
#keyframes fromBottom
{
0%
{
opacity: 0;
transform: translateY(100px);
}
100%
{
opacity: 1;
transform: translateY(0);
}
}
.btn--animated
{
animation: fromBottom .5s ease-out;
}
I expect the button to move from bottom to its original position when page is loaded.
Try adding display: inline-block; to your .btn--animated and it'll work.
.header
{
background-image: url(https://images2.minutemediacdn.com/image/upload/c_crop,h_2450,w_4368,x_0,y_165/f_auto,q_auto,w_1100/v1562080363/shape/mentalfloss/29942-gettyimages-155302141.jpg);
background-blend-mode: multiply;
height: 80vh;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 70%);
position: relative;
}
.header::after
{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(to bottom right, #34c9eb, #0c4f5e);
opacity: 0.9;
z-index: -1;
}
.header__logo-box
{
position: absolute;
top: 5px;
left: 0;
width: 80px;
}
.header__logo
{
width: 100%;
height: 100%;
}
.header__text-box
{
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.heading-primary--main
{
display: block;
}
.heading-primary--sub
{
display: block;
}
.btn
{
padding: 10px 30px;
text-decoration: none;
color: inherit;
border-radius: 100px;
position: relative;
}
.btn--white
{
background-color: #fff;
}
.btn::after
{
position: absolute;
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: all .4s;
background-color: red;
z-index: -1;
border-radius: 100px;
}
.btn:hover::after
{
transform: scaleX(1.4) scaleY(1.6);
opacity: 0;
}
/* this animation not working */
#keyframes fromBottom
{
0%
{
opacity: 0;
transform: translateY(100px);
}
100%
{
opacity: 1;
transform: translateY(0);
}
}
.btn--animated
{
display: inline-block;
animation: fromBottom .5s ease-out;
}
<header class="header">
<div class="header__logo-box">
<img src="https://dtgxwmigmg3gc.cloudfront.net/imagery/assets/derivations/icon/256/256/true/eyJpZCI6ImE4OWEzMGU2YTg5NTViYjcxZWY1OTJiNDlkYjZjMTRhLmpwZyIsInN0b3JhZ2UiOiJwdWJsaWNfc3RvcmUifQ?signature=8735e0713b1bd34828e75056d2c51efc7ffc62c0167dcb80e7d66fe8550b9bc6" alt="Logo" class="header__logo">
</div>
<div class="header__text-box">
<h1 class="heading-primary">
<span class="heading-primary--main">Outdoors</span>
<span class="heading-primary--sub">is where life happens</span>
</h1>
Discover our tours
</div>
</header>
So this issue has been bugging me for quite a while. I have this div container that centers an overflow image to the center.
However in Safari, the icon inside the div is not positioned in the center. Instead it is at the top. It works fine in other browsers though. Only Safari has this bug.
I attached a fiddle below. Appreciate any help! :)
JSfiddle demo
var $container = $('#page');
$container.masonry({
columnWidth: '.grid-sizer',
itemSelector: '.item',
percentPosition: true,
gutter: 10
});
#page .item {
width: calc(16.66% - 10px);
display: inline-block;
height: 0;
float: left;
padding-bottom: 16.66%;
overflow: hidden;
background-color: salmon;
margin: 5px;
position: relative;
}
#page .item.s1 {
width: calc(50% - 10px);
padding-bottom: 50%;
overflow: hidden;
background-color: navy;
}
.item > a {
/* position: relative; */
display: block;
overflow: hidden;
color: white;
}
.item:hover .grid-image:after {
background: rgba(0, 0, 0, .7);
}
.item:hover .grid-image > img {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
-o-transform: scale(1.1);
transform: scale(1.1);
}
.item:hover .item-caption {
opacity: 1;
z-index: 3;
visibility: visible;
}
.item-caption,
.grid-image > img,
.grid-image:after {
-webkit-transition: all 0.3s ease-in-out 0s;
-moz-transition: all 0.3s ease-in-out 0s;
-ms-transition: all 0.3s ease-in-out 0s;
-o-transition: all 0.3s ease-in-out 0s;
transition: all 0.3s ease-in-out 0s;
}
.item-caption {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(29, 106, 154, 0.72);
color: #fff;
visibility: hidden;
text-align: center;
opacity: 0;
display: table;
height: 100%;
width: 100%;
}
.item-caption > div {
display: table-cell;
height: 100%;
vertical-align: middle;
}
.grid-image {
position: relative;
overflow: hidden;
}
.grid-image img {
display: block;
overflow: hidden;
}
.grid-image:after {
position: absolute;
display: block;
content: "";
height: 100%;
width: 100%;
top: 0;
left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/masonry/3.3.2/masonry.pkgd.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" />
<div class="container-fluid">
<div id="page">
<!-- GRID ITEM -->
<div class="item s1">
<a href="#">
<div class="grid-image">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Pleiades_large.jpg/1024px-Pleiades_large.jpg">
</div>
<div class="item-caption">
<div>
<h5>I want this to be center</h5>
</div>
</div>
</a>
</div>
<!-- /GRID ITEM -->
</div>
</div>
</body>
</html>
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>