I'm working on some basic FreeCodeCamp challenges, and I'm trying to use React Transition Group to achieve some pretty simple animations. Here's the CodePen.
What I've run in to is that I can't find out how to have the "quote card" horizontally and vertically centered, and also have my animations (that I'm using React Transition Group to trigger) perform a translation on it. I have the element that I'm trying to move (#quote-box
) centered with the following css:
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
Here're the "move" CSS classes that I'm using with the Transition Group:
.move-enter {
opacity: 0.01;
transform: translate(-200px, 0);
}
.move-enter-active {
opacity: 1;
transform: translate(0, 0);
transition: all 500ms ease-in 200ms;
}
.move-exit {
opacity: 1;
transform: translate(0, 0);
}
.move-exit-active {
opacity: 0.01;
transform: translate(200px, 0);
transition: all 500ms ease-in 200ms;
}
I assume that I should be setting the transition
properties to be left
instead of all
, but I'm a little lost in what is preventing the movement from happening. Should I also have a move-exited
and move-entered
class with the appropriate positioning? Thanks in advance!
There is a pretty major hint as to what might be going wrong here, and that is the fact that in your CodePen, the cards successfully animate their opacity
but not their transform
. That tells you that something is working as expected, just not all of the transition.
So, our first step would be to investigate the transition as it happens. Indeed, if we slow down the CSS transition duration to 20 seconds and set the <ReactTransitionGroup.CSSTransition>
timeout also to 20 seconds, and inspect the element div#quote-box
with devtools as the transition is happening, we see something fishy:
Your CSS transform property for #quote-box
is overriding the transition group transform property for .move-enter-active
(as expected - see CSS selector specificity) (you can tell because the transform
property in .move-enter-active
is crossed out). In other words, your CSS transition group transform is never applied, but the opacity
transition is unaffected because #quote-box
does not set that property.
There are a few potential solutions here. One of the most simple involves two steps:
#quote-box
from an ID to a class (.quote-box
) - (you should absolutely do this anyway, and also for any IDs on the page, because you should only ever have a single instance of the same named ID on the page, and with CSS transition group you will have at least two at some points.) This will also ensure that your CSS transition group .move-*
selectors will have the proper priority.// CSS
.quote-box {
// etc
}
// JSX
<div className="quote-box" >
{/* etc */}
</div>
calc()
function to calculate the position of the quote box. This is because normally you would not be able to center the quote box with transform(-50%, -50%)
and offset its position for the transition with transform(-200px, 0)
at the same time. To do so, we must use calc()
to combine both the centering transform and the transition offset at the same time, i.e. transform: translate(calc(-50% - 200px), -50%);
:.move-enter {
opacity: 0.01;
transform: translate(calc(-50% - 200px), -50%);
}
.move-enter-active {
opacity: 1;
transform: translate(-50%, -50%);
transition: all 500ms ease-in 200ms;
}
.move-exit {
opacity: 1;
transform: translate(-50%, -50%);
}
.move-exit-active {
opacity: 0.01;
transform: translate(calc(-50% + 200px), -50%);
transition: all 500ms ease-in 200ms;
}