w-- w-- - 3 months ago 24
CSS Question

React, TransitionGroup, Velocity.js - make route tranistion animations align vertically

I'm using React TransitionGroup and Velocity to animate transitions between routes.

I'm trying to do a simple animation where the destination route component slides in from the left and the source route slide outs the right.

I have that animation running now, but they don't get aligned vertically. i.e. the new component gets added to the dom on top of the old one so we get what is in the screenshot below. This is when we navigate from Edit to Preview. The Form header is part of Edit and gets pushed to the bottom as Preview comes in.

What happens

Here is what the DOM looks like as the animation is running.

enter image description here

I'm sure I just need some css to achieve this, but not sure how to go about it.

example of Preview code:

import React from 'react';
import ReactDom from 'react-dom';
import Velocity from 'velocity-animate';
import 'velocity-animate/velocity.ui';

class Preview extends React.Component{
componentWillEnter(callback){
const el = ReactDom.findDOMNode(this);
if (!el) {
console.error('not el!', el);
}
Velocity(el, 'transition.slideLeftBigIn', {duration: 1000, complete: callback});
}

componentWillLeave (callback) {
const el = ReactDom.findDOMNode(this);
console.log('otw out')
Velocity(el, 'transition.slideRightBigOut', {duration: 1000, complete: callback});
}

render(){
return (
<div>
<h2>Preview</h2>
<img src=""/>
</div>
);
}
}


Transition Group defintion in App.jsx

<TransitionGroup>
{React.cloneElement(this.props.children, {
key: Math.random()
})}
</TransitionGroup>

Answer

Your instinct to solve this with CSS was right on. The cause is elements that have display: block and `position: static' will stack up vertically in source order (all other things equal).

https://jsfiddle.net/ez10xbrv/

You can change the animating components to have position: absolute and their container to have position: relative so they don't leave space for previous siblings. Note that if you go this route, your container (the <span> in your example) will not have any natural size so you may need to assign it a height and width. CSS Tricks has some good information on positioning that might help.

https://jsfiddle.net/ez10xbrv/1/

Comments