CSS Transition to specific location - javascript

I found an example, credit given to: http://jsfiddle.net/g9dn1a09/ and I am trying to modify it so that the CSS element transitions when clicked to given coordinates and then repeats.
The issue I am having is that my code is transitioning the element to different than needed coordinates.
How can I make this happen?
Thank you
JavaScript
var $box = $('.box'),
$btn = $('.toggle');
$box.on('click', function() {
var $this = $(this);
if ($this.hasClass('right')) {
$this.removeClass('right').addClass('down');
}
else if ($this.hasClass('down')) {
$this.removeClass('down').addClass('left');
}
else if ($this.hasClass('left')) {
$this.removeClass('left').addClass('up');
}
else if ($this.hasClass('up')) {
$this.removeClass('up').addClass('right');
}
else {
$this.addClass('right');
}
});
CSS
.box {
width: 50px;
height: 50px;
background-color: blue;
transition: transform 1s;
}
.right {
-webkit-transform-origin: 100% 50%;
transform: translateX(100px);
}
.down {
-webkit-transform-origin: 100% 50%;
transform: translatey(100px);
}
.left {
-webkit-transform-origin: 100% 50%;
transform: translatex(100px);
}
.up {
-webkit-transform-origin: 100% 50%;
transform: translatey(0px);
}
HTML
<div class="box"></div>

You need to cumulate the translation and not define a new one each time because you will simply reconsider the initial state and you won't have any continuity in your mouvement:
var $box = $('.box'),
$btn = $('.toggle');
$box.on('click', function() {
var $this = $(this);
if ($this.hasClass('right')) {
$this.removeClass('right').addClass('down');
} else if ($this.hasClass('down')) {
$this.removeClass('down').addClass('left');
} else if ($this.hasClass('left')) {
$this.removeClass('left').addClass('up');
} else if ($this.hasClass('up')) {
$this.removeClass('up').addClass('right');
} else {
$this.addClass('right');
}
});
.box {
width: 50px;
height: 50px;
background-color: blue;
transition: transform 1s;
}
.right {
transform: translateX(100px) translateY(0);
}
.down {
transform: translateX(100px) translateY(100px);
}
.left {
transform: translateX(0) translateY(100px);
}
.up {
transform:translateX(0) translateY(0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box"></div>

Related

Why the onAnimationEnd does not trigger when switching the focus to other tab of the browser?

I am trying to build a split-flap.
Here is my code:
let baseDiv, lowerDiv, middleDiv, upperDiv;
let intervalId;
document.addEventListener("DOMContentLoaded", () => {
baseDiv = document.getElementById("base");
lowerDiv = document.getElementById("lower");
middleDiv = document.getElementById("middle");
upperDiv = document.getElementById("upper");
});
let backward = () => {
middleDiv.innerHTML = baseDiv.innerHTML;
lowerDiv.classList.add("rotate0to90");
middleDiv.className = "upperHalfCard-after transform0to_90 zIndex4";
}
let forward = () => {
middleDiv.innerHTML = baseDiv.innerHTML;
upperDiv.classList.add("rotate0to_90");
middleDiv.className = "lowerHalfCard-after transform0to90 zIndex4";
}
let handler = obj => {
console.log(obj.id);
switch (obj.id) {
case "lower":
lowerDiv.classList.replace("zIndex4", "zIndex2");
middleDiv.classList.add("rotate_90to0");
break;
case "middle":
upperDiv.innerHTML = baseDiv.innerHTML;
lowerDiv.innerHTML = baseDiv.innerHTML;
middleDiv.className = "hide";
upperDiv.className = "upperHalfCard-after zIndex4";
lowerDiv.className = "lowerHalfCard-after zIndex2";
break;
case "upper":
middleDiv.classList.add("rotate90to0");
upperDiv.classList.replace("zIndex4", "zIndex2");
break;
default:
break;
}
}
let start = () => {
intervalId = setInterval(() => {
console.log("Kicked by interval");
forward();
}, 3000);
}
let stop = () => {
clearInterval(intervalId);
}
.fullCard,
.lowerHalfCard,
.upperHalfCard,
.fullCard-after,
.lowerHalfCard-after,
.upperHalfCard-after {
background-color: inherit;
border-radius: 10px;
height: 100%;
width: 100%;
position: absolute;
align-items: inherit;
display: inherit;
justify-content: inherit;
}
.fullCard-after::after,
.upperHalfCard-after::after {
content: "";
display: block;
position: absolute;
height: 4px;
background-color: inherit;
width: 100%;
top: calc(50% - 2px);
}
.lowerHalfCard-after::after {
content: "";
display: block;
position: absolute;
height: 4px;
background-color: inherit;
width: 100%;
top: calc(50% - 2px);
}
.lowerHalfCard,
.lowerHalfCard-after {
clip-path: polygon(0% 50%, 100% 50%, 100% 100%, 0% 100%);
}
.upperHalfCard,
.upperHalfCard-after {
clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 0% 50%);
}
.splitFlap {
background-color: black;
box-sizing: border-box;
border-radius: 10px;
color: white;
font-weight: bold;
font-family: arial;
font-size: 5.5em;
width: 100px;
height: 150px;
position: relative;
align-items: center;
display: flex;
justify-content: center;
transform-style: preserve-3d;
}
.rotate0to90 {
animation-name: r0to90;
}
.rotate90to0 {
animation-name: r90to0;
}
.rotate0to_90 {
animation-name: r0to_90;
}
.rotate_90to0 {
animation-name: r_90to0;
}
.rotate0to90,
.rotate90to0,
.rotate0to_90,
.rotate_90to0 {
animation-duration: 0.3s;
animation-fill-mode: forwards;
}
#keyframes r0to90 {
from {
transform: rotateX(0deg);
}
to {
transform: rotateX(90deg);
}
}
#keyframes r90to0 {
from {
transform: rotateX(90deg);
}
to {
transform: rotateX(0deg);
}
}
#keyframes r0to_90 {
from {
transform: rotateX(0deg);
}
to {
transform: rotateX(-90deg);
}
}
#keyframes r_90to0 {
from {
transform: rotateX(-90deg);
}
to {
transform: rotateX(0deg);
}
}
.transform0to_90 {
transform: rotateX(-90deg);
}
.transform0to90 {
transform: rotateX(90deg);
}
.hide {
display: none
}
.zIndex2 {
z-index: 2;
}
.zIndex4 {
z-index: 4;
}
<div class="splitFlap">
<div id="base" class="fullCard-after zIndex2">
2
</div>
<div class="upperHalfCard-after zIndex4" id="upper" onAnimationEnd="handler(this)">
1
</div>
<div id="middle" class="hide" onAnimationEnd="handler(this)">
</div>
<div class="lowerHalfCard-after zIndex2" id="lower" onAnimationEnd="handler(this)">
1
</div>
</div>
<p>
<button onClick="start()">
Start
</button>
<button onClick="stop()">
Stop
</button>
</p>
The code works fine where the tab is on focus.
And you can see the onAnimationEnd event handler and interval handler work properly(i.e. 1 interval event trigger 2 onAnimationEnd event.).
Unfortunately, when switching the browser focus to another tab for about 1 min, the onAnimationEnd event handler seems to be not stable(i.e. sometimes only an interval event is triggered, and no onAnimationEnd event is triggered, sometimes the onAnimationEnd event handler can be resume).
What's going on? how can I fix it?

stacked cards carousel: looping z-index with jquery

I'm trying to create a carousel of stacked cards using CSS animations and Jquery.
The DOM elements are the following:
<div class="container">
<div class="card active" style="background:orange;z-index:4">
1
</div>
<div class="card" style="background:tan;z-index:3">
2
</div>
<div class="card" style="background:pink;z-index:2">
3
</div>
<div class="card" style="background:blue;z-index:1">
4
</div>
</div>
what i need to to is having
the z-index:4 card to become z-index:1
the z-index:3 card to become z-index: 4
the z-index:2 card to become z-index: 3
the z-index:1 card to become z-index: 2
you get the point: the first card needs to be pushed back in the stack, the others should move "up" one level.
Here's a semi-working fiddle: https://jsfiddle.net/p34yzmhv/
I'm no JS expert, i really don't know how to loop the zindex value. I've been reading similar questions here on stackoverflow but couldn't find something exactly similar to my problem.
thanks any hint or help is greatly appreciated.
You can put the z-index within a class and then change the class.
This also allows you to update the positions currently set with .card+.card+.card(etc) without which, your card1 would go to the back, but be position to be unseeable.
The alternative would be to move the elements in the DOM, which may or may not be simpler depending on what else you do with the cards.
Keeping with z4 = z-index=4 => positioned at the front (rather than more logical 1=at the front), add classes:
.z4 {
z-index: 4;
}
.z3 {
transform: rotate(2deg) translate3d(-50%, -50%, 0);
z-index: 3;
}
etc
Then, each iteration, remove all classes and add them back starting with the now current .active. .nextAll gives the following siblings while .prevAll gives the preceding siblings. Only .prevAll gives them in the reverse order so you also need to reverse that.
$(".card").removeClass("z1 z2 z3 z4");
let z=4;
$(".card.active").addClass("z"+z);
$(".card.active").nextAll(".card").each((i, e) => { z--; $(e).addClass("z"+z); });
$($(".card.active").prevAll(".card").get().reverse()).each((i, e) => { z--; $(e).addClass("z"+z); });
// console.log to confirm they're in the correct order
$(".card").each((i, e) => console.log(i, $(e).text(), e.className));
Updated snippet:
$(".btn2").click(function () {
setTimeout(function () {
var $next = $(".card.active").removeClass("active").next(".card");
if ($next.length) {
$next.addClass("active");
} else {
$(".card:first").addClass("active");
}
$(".card").removeClass("z1 z2 z3 z4");
var z=4;
$(".card.active").addClass("z"+z);
$(".card.active").nextAll(".card").each((i, e) => { z--; $(e).addClass("z"+z); });
$($(".card.active").prevAll(".card").get().reverse()).each((i, e) => { z--; $(e).addClass("z"+z); });
$(".card").each((i, e) => console.log(i, $(e).text(), e.className));
}, 1);
$(".card.active")
.addClass("animation")
.one(
"animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
function () {
$(".card").removeClass("animation");
}
);
});
#keyframes animation {
0% {
transform: rotate(0) translate3d(-50%, -50%, 0) scale(1);
opacity: 1;
z-index: 10;
}
15% {
opacity: 1;
z-index: 10;
transform: rotate(2deg) translate3d(-50%, -50%, 0) scale(1.1);
}
50% {
transform: rotate(-40deg) translate3d(-320%, -50%, 0) scale(0.1);
opacity: 0;
z-index: 0;
}
75% {
opacity: 1;
}
100% {
transform: rotate(0) translate3d(-50%, -50%, 0) scale(1);
opacity: 1;
z-index: 0;
}
}
.animation {
animation: animation 1s forwards cubic-bezier(0.83, 0, 0.17, 1);
}
.card {
transform-origin: center;
transform: rotate(0) translate3d(-50%, -50%, 0);
transition: all 1s cubic-bezier(0.22, 1, 0.36, 1);
&.active {
transform: rotate(0) translate3d(-50%, -50%, 0)!important;
}
}
// --------------------------------------------
// --------------- DEMO STYLES ----------------
// --------------------------------------------
html {
height: 100%;
}
body {
box-sizing: border-box;
margin: 0;
padding: 0;
* {
box-sizing: inherit;
}
}
.btn2 {
position: fixed;
left: 50%;
bottom: 10%;
transform: translateX(-50%) translateY(-50%);
background: coral;
cursor: pointer;
color: white;
padding: 24px;
text-transform: uppercase;
z-index: 50;
zoom: 1.2;
}
.container {
width: 420px;
height: 480px;
background: #eee;
overflow: hidden;
margin: 0 auto;
position: relative;
padding: 20px;
}
.card {
border-radius: 24px;
display: flex;
align-items: center;
justify-content: center;
min-height: 400px;
max-width: 320px;
position: absolute;
top: 50%;
left: 50%;
width: 100%;
&.active {
box-shadow: 0 0 20px rgba(black, 0.25);
border: 1px solid black;
}
}
.z4 {
z-index: 4;
}
.z3 {
transform: rotate(2deg) translate3d(-50%, -50%, 0);
z-index: 3;
}
.z2 {
transform: rotate(4deg) translate3d(-50%, -50%, 0);
z-index: 2;
}
.z1 {
transform: rotate(6deg) translate3d(-50%, -50%, 0);
z-index: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="card active z4" style="background:orange">1</div>
<div class="card z3" style="background:tan">2</div>
<div class="card z2" style="background:pink">3</div>
<div class="card z1" style="background:blue">4</div>
</div>
<div class="btn2">
animate
</div>
Updated fiddle: https://jsfiddle.net/7z39mqdt/

Event listener for key class behaves unexpectedly

The log for the closeBox function is supposed to be box hidden but its not. its showing box shown hidden.
Can anyone explain why the classes of the box is not what is expected? This is the code:
const showBoxBtn = document.querySelector('.showBox');
const closeBoxBtn = document.querySelector('.closeBox');
const box = document.querySelector('.box');
const showBox = function () {
box.classList.add('will-show');
box.classList.remove('hidden');
box.addEventListener("animationend", function(){
box.classList.remove('will-show');
box.classList.add('shown');
console.log(box.classList.value);
});
}
const closeBox = function () {
box.classList.add('will-hide');
//shown class was removed here
box.classList.remove('shown');
box.addEventListener("animationend", function(){
box.classList.remove('will-hide');
box.classList.add('hidden');
//supposed to be box hidden only
console.log(box.classList.value);
});
}
showBoxBtn.addEventListener('click', showBox);
closeBoxBtn.addEventListener('click', closeBox);
.box {
width: 100px;
height: 100px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #000;
display:flex;
position: absolute;
}
#keyframes slide-in-top {
0% {
transform: translateY(-1000px);
opacity: 0;
}
100% {
transform: translateY(0), translate(-50%, -50%);
opacity: 1;
}
}
.will-show {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
.will-hide {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
animation-direction: reverse;
}
.shown {
display: block;
}
.hidden {
display: none;
}
<button class="showBox">Show</button>
<button class="closeBox">Close</button>
<div class="box hidden"></div>
Your issue is that .addEventListener("animationed") will fire when your animation ends, for both when your box is shown and when it is closed. You can add the {once: true} option to your addEventListener to only add the listener once so it doesn't fire on subsequent animationed events:
const showBoxBtn = document.querySelector('.showBox');
const closeBoxBtn = document.querySelector('.closeBox');
const box = document.querySelector('.box');
const showBox = function() {
box.classList.add('will-show');
box.classList.remove('hidden');
box.addEventListener("animationend", function() {
box.classList.remove('will-show');
box.classList.add('shown');
console.log(box.classList.value);
}, {once: true});
}
const closeBox = function() {
box.classList.add('will-hide');
//shown class was removed here
box.classList.remove('shown');
box.addEventListener("animationend", function() {
box.classList.remove('will-hide');
box.classList.add('hidden');
//supposed to be box hidden only
console.log(box.classList.value);
}, {once: true});
}
showBoxBtn.addEventListener('click', showBox);
closeBoxBtn.addEventListener('click', closeBox);
.box {
width: 100px;
height: 100px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #000;
display: flex;
position: absolute;
}
#keyframes slide-in-top {
0% {
transform: translateY(-1000px);
opacity: 0;
}
100% {
transform: translateY(0), translate(-50%, -50%);
opacity: 1;
}
}
.will-show {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
.will-hide {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
animation-direction: reverse;
}
.shown {
display: block;
}
.hidden {
display: none;
}
<button class="showBox">Show</button>
<button class="closeBox">Close</button>
<div class="box hidden"></div>
It's because you register a new animationend event listener each time you click a button.
So when you click Close button it fires both close and show events listeners.
You'll need either remove that event when it's complete, or register it once:
const showBoxBtn = document.querySelector('.showBox');
const closeBoxBtn = document.querySelector('.closeBox');
const box = document.querySelector('.box');
box.addEventListener("animationend", function(){
if (box.classList.contains("will-hide"))
{
box.classList.add('hidden');
}
else
{
box.classList.add('shown');
}
box.classList.remove('will-hide');
box.classList.remove('will-show');
console.log(box.classList.value);
});
const showBox = function () {
if (box.classList.contains("shown"))
return;
box.classList.add('will-show');
box.classList.remove('hidden');
}
const closeBox = function () {
if (box.classList.contains("hidden"))
return;
box.classList.add('will-hide');
//shown class was removed here
box.classList.remove('shown');
}
showBoxBtn.addEventListener('click', showBox);
closeBoxBtn.addEventListener('click', closeBox);
.box {
width: 100px;
height: 100px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #000;
display:flex;
position: absolute;
}
#keyframes slide-in-top {
0% {
transform: translateY(-1000px);
opacity: 0;
}
100% {
transform: translateY(0), translate(-50%, -50%);
opacity: 1;
}
}
.will-show {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
.will-hide {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
animation-direction: reverse;
}
.shown {
display: block;
}
.hidden {
display: none;
}
<button class="showBox">Show</button>
<button class="closeBox">Close</button>
<div class="box hidden"></div>
implemented a little state-machine. This is nicer/less jumpy when someone clicks the show/close buttons multiple times.
const showBoxBtn = document.querySelector('.showBox');
const closeBoxBtn = document.querySelector('.closeBox');
const box = document.querySelector('.box');
// what are the allowed state-changes
const stateChanges = {
"hidden": {
"will-show": true
},
"will-hide": {
"hidden": true,
//"will-show": true
},
"shown": {
"will-hide": true
},
"will-show": {
"shown": true,
//"will-hide": true
}
};
const setState = (toState) => {
for (let fromState in stateChanges) {
if (box.classList.contains(fromState) && stateChanges[fromState][toState]) {
box.classList.remove(fromState);
box.classList.add(toState);
return true;
}
}
return false;
}
const showBox = function() {
setState('will-show');
}
const closeBox = function() {
setState('will-hide');
}
const animationend = function() {
//meh, try which one works
setState('shown') || setState('hidden');
console.log(box.classList.value);
}
showBoxBtn.addEventListener('click', showBox);
closeBoxBtn.addEventListener('click', closeBox);
box.addEventListener("animationend", animationend);
.box {
width: 100px;
height: 100px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #000;
display: flex;
position: absolute;
}
#keyframes slide-in-top {
0% {
transform: translateY(-1000px);
opacity: 0;
}
100% {
transform: translateY(0), translate(-50%, -50%);
opacity: 1;
}
}
.will-show {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
.will-hide {
animation: slide-in-top 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
animation-direction: reverse;
}
.shown {
display: block;
}
.hidden {
display: none;
}
<button class="showBox">Show</button>
<button class="closeBox">Close</button>
<div class="box hidden"></div>
I'm not sure about the state changes "will-hide" -> "sill-show" and vice versa.
That's why I commented them out. If you don't need them/won't allow them, you can simplify that part to:
const stateChanges = {
"hidden": "will-show",
"will-show": "shown",
"shown": "will-hide",
"will-hide": "hidden"
}
// and
if (box.classList.contains(fromState) && stateChanges[fromState] === toState) {

How can I restart a CSS animation with random values in a loop?

I have an element which is randomly animated with CSS and JS with the help of CSS custom properties in the following way:
var myElement = document.querySelector('#my-element');
function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}
function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
/* restart the animation */
var clone = myElement.cloneNode(true);
myElement.parentNode.replaceChild(clone, myElement);
}
myElement.addEventListener('animationend', changeAnimation, false);
#my-element {
width: 50px;
height: 50px;
background: #333;
}
:root {
--animation-name: vibrate-1;
}
#my-element {
animation: 3.3s 1 alternate var(--animation-name);
}
#keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}
#keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}
#keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}
<div id="my-element"></div>
The idea behind is to have a set of animations which switch on each animation’s end randomly to another one. (that for the opacity in the end is always 0 to make a smooth invisible switch.)
Now, surprisingly, this code above runs just fine, except that it does only once and then stop.
I now there are JS loop techniques but I have no idea how to exactly implement them inside this workflow.
Can someone help me?
When you replace the element with the cloned element, you should reassign the animationend event listener:
var clone = myElement.cloneNode(true);
clone.addEventListener('animationend', changeAnimation, false);
myElement.parentNode.replaceChild(clone, myElement);
By the way, variables in JavaScript can't contain -, so my-element should be myElement.
Another simple idea is to rely on animationiteration and make the animation to run infinite then you no more need to clone the element. You simply change the animation name each iteration and you will have the needed effect:
var myElement = document.querySelector('#my-element');
function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}
function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
}
myElement.addEventListener('animationiteration', changeAnimation, false);
#my-element {
width: 50px;
height: 50px;
background: #333;
}
#my-element {
animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
}
#keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
background:green;
}
100% {
opacity: 0;
transform: scale(0.9);
}
}
#keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
background:red;
}
100% {
opacity: 0;
transform: scale(0.5);
}
}
#keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
background:blue;
}
100% {
opacity: 0;
transform: scale(0.8);
}
}
<div id="my-element"></div>
Another way is to simply keep one animation and adjust the scale values (or any other values) and you will have a better random behavior.
var myElement = document.querySelector('#my-element');
function changeAnimation() {
var n1 = Math.random();
myElement.style.setProperty('--s1',n1);
var n2 = Math.random();
myElement.style.setProperty('--s2',n2);
var c1 = Math.floor(Math.random()*255);
myElement.style.setProperty('--c1',c1);
var c2 = Math.floor(Math.random()*255);
myElement.style.setProperty('--c2',c2);
}
myElement.addEventListener('animationiteration', changeAnimation, false);
#my-element {
width: 50px;
height: 50px;
background: #333;
}
#my-element {
animation: 3.3s alternate infinite vibrate;
}
#keyframes vibrate {
0% {
opacity: 0;
transform: scale(var(--s1,0.95));
}
50% {
opacity: 1;
transform: scale(1);
background:rgb(255,var(--c1,0),var(--c2,0));
}
100% {
opacity: 0;
transform: scale(var(--s2,0.9));
}
}
<div id="my-element"></div>

3d flip animation not working in chrome

I wanted to create a card with text which will flip and show a backside with some other text, whenever you click on the "card" (div). I checked for any mistakes and stuff but somehow its not working on chrome.
HTML:
<div class="card effect__EFFECT">
<div class="card__front">
<span class="card__text">front</span>
</div>
<div class="card__back">
<span class="card__text">back</span>
</div>
</div>
CSS:
.card {
position: relative;
float: left;
padding-bottom: 25%;
width: 25%;
text-align: center;
}
.card__front,
.card__back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.card__front,
.card__back {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transition: -webkit-transform 0.3s;
transition: transform 0.3s;
}
.card__front {
background-color: #ff5078;
}
.card__back {
background-color: #1e1e1e;
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.card.effect__click.flipped .card__front {
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.card.effect__click.flipped .card__back {
-webkit-transform: rotateY(0);
transform: rotateY(0);
}
Javascript:
(function() {
var cards = document.querySelectorAll(".card.effect__click");
for ( var i = 0, len = cards.length; i < len; i++ ) {
var card = cards[i];
clickListener( card );
}
function clickListener(card) {
card.addEventListener( "click", function() {
var c = this.classList;
c.contains("flipped") === true ? c.remove("flipped") : c.add("flipped");
});
}
})();
Here is a working fiddle http://jsfiddle.net/hzsbzxw6/ it seems that this should all work, it could be the way you're embedding the script.
<script type = "text/javascript">
Try fixing that, or ultimately not embedding it inline.

Categories