'Flipping a card, CSS animation for web app
I've managed to build a card in React with a front and backside and have it flip successfully on hover with CSS. However, I want to flip it on click/touch.
I tried setting the transform property to a class and toggling that class on click but no luck.
How would you accomplish this?
This is how I am currently flipping it via hover:
.card {
position: relative;
perspective: 800px;
transition: transform 1s ease;
perspective: 1000px;
}
.card > * {
width: 10rem;
transition: transform 1s ease;
backface-visibility: hidden;
}
.card:hover > .card__front {
transform: rotateY(180deg);
}
.card:hover > .card__back {
transform: rotateY(0);
}
and my JSX
<div className={styles.card} >
{/* FRONTSIDE */}
<div className={styles.card__front}>
//FRONTSIDE CONTENT
</div>
{/* BACKSIDE */}
<div className={styles.card__back}>
//BACKSIDE CONTENT
</div>
</div>
UPDATE
This function works, it toggles the flip class on and off on my desired element. However, no animation happens once the class is added. The .flip class does the exact same thing as the :hover did though..
//function to toggle class
const flip = (element) => {
console.log(element);
element.classList.toggle("flip");
};
//the css class
.flip {
transform: rotateY(180deg);
}
Solution 1:[1]
You may use js to add a style to the element.
What you forgot to add is pretty simple, you forgot transition: transform 1s on the class and perspective: 1000px. The more less the more intense the effect is.
HTML:-
<link href="style.css" rel="stylesheet" type="text/css">
<script src="script.js"></script>
<div class="card-warpper">
<span onclick="flipCard()" class="card">
<div class="front">
Aye
</div>
<div class="back">
Bye
</div>
</span>
</div>
CSS:- (You will edit it based on your needs)
body {
background: blue;
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.card-warpper {
width: 50%;
height: 30%;
perspective: 1000px;
}
.card {
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
transform-style: preserve-3d;
transition: transform 1s;
}
.card-clicked {
transform: rotateY(180deg);
}
.front {
backface-visibility: hidden;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 100%;
height: 100%;
background-color: white;
color: black;
font-size: 2rem;
}
.back {
backface-visibility: hidden;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
width: 100%;
height: 100%;
background: black;
color: antiquewhite;
font-size: 2rem;
transform: rotateY(180deg);
}
Finally, JS:-
function flipCard() {
let card = document.getElementsByClassName("card")[0];
card.classList.toggle("card-clicked");
}
If this answer helped you, please dont hesitate to click the check mark beside it to accept the answer.
Solution 2:[2]
I'm still learning javascript but this is what i came up with...
I made a snippet using javascript, you can click the "card" and it goes to the back and when you "mouse out" it rotates back to front or if you comment out the second cards.forEach and you can click another card and it rotates back to front and the card you clicked rotates to the back.
I made a class called ".card__inner.is-flipped". With the "cards" variable declared in the javascript that targets all of the ".card__inner"'s i added and removed the ".is-flipped" class on "click" and "mouseleave" to each card.
let cards = document.querySelectorAll('.card__inner');
cards.forEach(el => {
el.addEventListener('click', function() {
cards.forEach(el => el.classList.remove('is-flipped'));
el.classList.add('is-flipped');
});
});
cards.forEach(el => {
el.addEventListener('mouseleave', function() {
cards.forEach(el => el.classList.remove('is-flipped'));
});
});
.cardRowWrapper { //RowWrapper CARD
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
flex-wrap: wrap;
width: 45rem;
height: 35rem;
perspective: 800px;
z-index: 100;
}
.card__inner { //Skills circle
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
height: 12rem;
width: 12rem;
border-radius: 50%;
background: green;
transition: transform 1s;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
position: relative;
}
.card__inner.is-flipped {
transform: rotateY(180deg);
background: yellow;
}
.card__face {
position: absolute;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-o-backface-visibility: hidden;
overflow: hidden;
}
.card__face--front {
display: flex;
backface-visibility: hidden;
align-items: center;
justify-content: center;
}
.card__face--back {
display: block;
transform: rotateY(180deg);
}
<div class="cardRowWrapper">
<div class="card__inner">
<div class="card__face card__face--front">
<p>This is the front</p>
</div>
<div class="card__face card__face--back">
<span class="skillsSubHeading">This is the back</span>
</div>
</div>
<div class="card__inner">
<div class="card__face card__face--front">
<p>This is the front</p>
</div>
<div class="card__face card__face--back">
<span class="skillsSubHeading">This is the back</span>
</div>
</div>
<div class="card__inner">
<div class="card__face card__face--front">
<p>This is the front</p>
</div>
<div class="card__face card__face--back">
<span class="skillsSubHeading">This is the back</span>
</div>
</div>
<div class="card__inner">
<div class="card__face card__face--front">
<p>This is the front</p>
</div>
<div class="card__face card__face--back">
<span class="skillsSubHeading">This is the back</span>
</div>
</div>
<div class="card__inner">
<div class="card__face card__face--front">
<p>This is the front</p>
</div>
<div class="card__face card__face--back">
<span class="skillsSubHeading">This is the back</span>
</div>
</div>
<div class="card__inner">
<div class="card__face card__face--front">
<p>This is the front</p>
</div>
<div class="card__face card__face--back">
<span class="skillsSubHeading">This is the back</span>
</div>
</div>
</div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
