I'm pretty new to react-transition-group and I'm trying to build a card flipping animation. I'm able to get the first side to flip but it doesn't like the idea of staying put onto the back side. Any ideas what I'm doing wrong here?
import {useState} from "react";
import {CSSTransition} from "react-transition-group";
import "./styles.css";
export default function App() {
const [flipped, setFlipped] = useState(false);
return (
<div className="card-container">
<button
className="card-button"
onClick={() => setFlipped(!flipped)}
>
<CSSTransition
in={flipped}
timeout={1000}
classNames="front-face-transition"
>
<div className="card-front">
<p>front-side</p>
</div>
</CSSTransition>
<CSSTransition
in={!flipped}
timeout={1000}
classNames="back-face-transition"
>
<div className="card-back">
<p>back-side</p>
</div>
</CSSTransition>
</button>
</div>
);
}
.App {
font-family: sans-serif;
text-align: center;
}
.card-container {
width: 250px;
height: 400px;
padding: 0;
margin: 0;
}
.card-container .card-button {
padding: 0;
margin: 0;
border: none;
cursor: pointer;
width: 100%;
height: 100%;
position: relative;
}
.front-face-transition-enter {
transform-style: preserve-3d;
transition: all 1000ms ease;
transform: rotateY(0deg);
}
.front-face-transition-enter-active {
transform: rotateY(180deg);
}
.front-face-transition-enter-done {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.back-face-transition-enter {
transform-style: preserve-3d;
transition: all 1000ms ease;
transform: rotateY(0deg);
display: block;
}
.back-face-transition-enter-active {
transform: rotateY(-180deg);
display: block;
}
.back-face-transition-enter-done {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.card-front {
display: none;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
Also, here's a working codesandbox link to this code in case that helps as well.
There's a lot to unpack here. There was no one error causing you issues, but a lot of little errors. I will try to address them as best I can. For the most part, your React is spot on, but the CSS is where you got into trouble.
tl;dr: here is a working code sandbox
activeclass. This is by convention, but with your particular example, they could be permanent properties on the card elements.flippedlogic is backwardsdisplay: noneon the front face, meaning it wasn't visible at all.exit-doneand aenter-doneif you expect the transform to stay (the 180deg turn). Set those rules to have the same transform value as theactiveclass, that will keep the side "staying put" after the animation.perspectiveproperty on the parent element to see any real 3d effect. This is a pixel value that represents how far away the viewer is from the element in z space.transparent, otherwise the card will cut through the background when moving in 3d space.I think that's everything.
Code
In general your code could be a lot DRYer. Look for shared styles of similar elements and group them together to avoid unnecessary cruft. I left a few ways to optimize in my code example, but for example you can see that
.front-face-transition-exit-doneand.front-face-transition-enterhave the same rules, put them together!Good luck with CSSTransitions, and let me know if you have any questions.