I am trying to use CSSTransitionGroup (or ReactTransitionGroup) to create a vertical smooth scroll effect for content as it appears and disappears from the dom.
I am aware of ways to animate such an effect using transition in pure css, but I need to be able to do this in React when an item appears in and then leaves the DOM, so CSSTransitionGroup seemed like the right solution.
While I am able to animate properties like color and opacity, I am unsuccessful in animating properties like height and/or max-height to achieve the gradual disappearance of the content from top to the bottom or bottom to the top.
How can I animate a smooth scroll effect like this when an item enters and leaves the DOM? My current code using the CSSTransitionGroup is as follows:
class App extends React.Component {
state = {
random: true
};
toggleItem = () => {
this.setState({
random: !this.state.random
});
};
render() {
console.log("random", this.state.random);
return (
<div>
<button onClick={this.toggleItem}>toggle item</button>
<br />
<CSSTransition
in={this.state.random}
timeout={400}
classNames="alert"
unmountOnExit
appear
enter={false}
>
<div class="back">
Hello adsffd asdfadfs asdfasd asdfasdf asdfasfa fdasfas asdfasdf
afdsafas asdfasd asdfasdf asdfadsf asdfads asdfads asdfasdf
asdfadsadsf world Hello adsffd asdfadfs asdfasd asdfasdf asdfasfa
fdasfas asdfasdf afdsafas asdfasd asdfasdf asdfadsf asdfads asdfads
asdfasdf asdfadsadsf world Hello adsffd asdfadfs asdfasd asdfasdf
asdfasfa fdasfas asdfasdf afdsafas asdfasd asdfasdf asdfadsf asdfads
asdfads asdfasdf asdfadsadsf world Hello adsffd asdfadfs asdfasd
asdfasdf asdfasfa fdasfas asdfasdf afdsafas asdfasd asdfasdf
</div>
</CSSTransition>
</div>
);
}
}
export default App;
And the current class I have for enter states is:
.alert-enter {
height: 0px;
visibility: hidden;
overflow: hidden;
}
.alert-enter-active {
height: auto;
overflow: auto;
visibility: visible;
transition: all 300ms;
}
You can add a white div and transition for it to wrap your text div
class App extends Component {
state = {
random: false
};
toggleItem = () => {
this.setState({
random: !this.state.random
});
};
render() {
return (
<div>
<button onClick={this.toggleItem}>toggle item</button>
<br />
<div className="back">
Hello adsffd asdfadfs asdfasd asdfasdf asdfasfa fdasfas asdfasdf
afdsafas asdfasd asdfasdf asdfadsf asdfads asdfads asdfasdf
asdfadsadsf world Hello adsffd asdfadfs asdfasd asdfasdf asdfasfa
fdasfas asdfasdf afdsafas asdfasd asdfasdf asdfadsf asdfads asdfads
asdfasdf asdfadsadsf world Hello adsffd asdfadfs asdfasd asdfasdf
asdfasfa fdasfas asdfasdf afdsafas asdfasd asdfasdf asdfadsf asdfads
asdfads asdfasdf asdfadsadsf world Hello adsffd asdfadfs asdfasd
asdfasdf asdfasfa fdasfas asdfasdf afdsafas asdfasd asdfasdf
<CSSTransition
in={this.state.random}
timeout={1000}
classNames="alert"
unmountOnExit
>
<div className="white" />
</CSSTransition>
</div>
</div>
);
}
}
style.css
.alert-enter {
transform: translateY(400px);
}
.alert-enter-active {
transform: translateY(0px);
transition: all 1000ms;
}
.alert-exit {
transform: translateY(0px);
}
.alert-exit-active {
transform: translateY(800px);
transition: all 3000ms;
}
.back {
position: relative;
overflow: hidden;
}
.white {
height: 100%;
position: absolute;
top: 0;
left: 0;
background: white;
width: 100%;
}
You can check here CodeSandBox. Hope it helps