« Back

💨

simple animations in React

on programming
last updated 11/30/20

There are plenty of ways to add page transitions to a React application, this tutorial outlines a really simple one. It requires minimal effort but can make your single page app look a lot more professional.


Before we get into animations for the different routes, we'll build a fade-in transition for our initial page load. This is pretty simple with the CSS animation property.


/* your-app/src/App.css */
body {
  animation: fadeIn 1s ease;
}

@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
        

Let's unpack that first ruleset. We're using a shorthand property instead of 3 separate declarations in the same block.


/* option a */
body {
  animation-name: fadeIn; /* specifying the name of our @keyframes animation */
  animation-duration: 1s; /* which should take 1 second to complete */
  animation-timing-function: ease; /* and start slowly, speed up, and finish slowly */
}

/* option b */
body {
  animation: fadeIn 1s ease; /* equivalent, much more concise declaration */
}
        

So we're binding our selector —body, the whole page — to this animation fadeIn which has 2 keyframes.

Keyframes are basically checkpoints in the life of a CSS animation. We're only setting two of them here, indicating that we want to begin the animation with opacity set to 0 and end it with opacity set to 1.


@keyframes fadeIn {
  0% { opacity: 0; } /* from */
  100% { opacity: 1; } /* to */
}
        

Tying the animation and keyframes declarations together, here's how we can interpret the code below in plain English:


/* your-app/src/App.css */
body {
  animation: fadeIn 1s ease;
}

@keyframes fadeIn {
  0% { opacity: 0; }
  100% { opacity: 1; }
}
        

Adding these seven lines of code to our stylesheet, we now have a fade-in transition on initial page load. Let's finish up with some transitions between our child routes.


First, head over to the react-fader package documentation and spend a few minutes reading through it.

In one of the code snippets provided, we see that the TransitionSwitch component from the react-router-transition-switch package can replace a Switch component.


import { Route, BrowserRouter as Router } from 'react-router-dom'
import TransitionSwitch from 'react-router-transition-switch'
import Fader from 'react-fader'

<Router>
  <TransitionSwitch component={Fader}>
    <Route path="/red" component={Red}/>
    <Route path="/green" component={Green} />
    <Route path="/blue" component={Blue} />
  </TransitionSwitch>
<Router>
        

We needed to swap in the TransitionSwitch component so that we can pass it a prop: our Fader component. On transitions between routes, this will fade out the old route's children and fade in those for the new one.


/* here's how I implemented this in my React app */
import './App.css'
import Navbar from './components/Navbar'
import { Route } from 'react-router-dom'
import TransitionSwitch from 'react-router-transition-switch'
import Fader from 'react-fader'
import Generator from './containers/Generator'
import IdeasIndex from './containers/IdeasIndex'
import About from './containers/About'

const App = () => {
  return (
    <div className="App">
      <Navbar />
      <TransitionSwitch component={Fader}>
        <Route exact path="/"> <Generator /> </Route>
        <Route exact path="/all"> <IdeasIndex /> </Route>
        <Route exact path="/about"> <About /> </Route>
      </TransitionSwitch>
    </div>
  )

}

export default App
        

I think the default settings look really clean but feel free to play with some of the other props detailed in the docs. Hope this helps :)