Creating React animations with Framer Motion
Well-considered animations can add an extra layer of polish to your projects. In this article, Nefe looks at Framer Motion and how you can use it within your React projects.
Table of contents
As developers, we want to give people the best user experience when they visit our sites. To ensure that, we make the sites easy to navigate, accessible, and quick to load.
We can also improve the user experience by adding animations to our websites. When done right, adding animations can leave a lasting impression on users and make websites more visually appealing.
In this article, we will explore how to add animations to React websites with Framer Motion, a popular animation library for React projects. This guide is useful for React developers looking to spice up their websites with eye-catching animations and transitions. We will also explore how to make the animations accessible to all users.
Prerequisites
This article requires knowledge of React to follow along with ease. However, code snippets and an online editor playground will be available to explore the code of the demo animations we will create.
The importance of animations in web design
Before diving into the coding aspect of this article, let’s explore some reasons why animations can improve web experiences:
- Improve user experience: Animations like page transitions and hover, scroll, loading, and text animations can elevate a website's overall user experience and make the website more delightful for visitors.
- Boost brand reputation: When executed well, animations can positively affect how people view a brand, thereby improving its reputation. A good example is Apple, which always includes beautiful animations on the landing pages of its products. These websites show Apple’s attention to detail and professionalism, ultimately increasing its brand recognition.
- Draws user attention and focus: We can use animations to drive a user’s attention to specific parts of a page. For example, we can apply a shake effect to an important notification to draw the user’s attention and ensure they don’t miss it. Another example is applying a fade and background darkening animation to the rest of a page when a user clicks on a photo gallery. This helps the image in view stand out.
- Provide visual feedback: We can use animations to give users visual cues and feedback based on their actions. For example, we can show a loading indicator when a user submits a form to show that the submission process is ongoing.
What is Framer Motion?
Framer Motion is a React library for adding animations and transitions to React-based websites and web applications. It allows us to create scroll-based, layout-based, and gesture-based animations. We can also use it to animate SVGs.
Developers often hesitate to add animations to their websites because they are concerned about the potential performance impact. However, Framer Motion is a lightweight library, which is 42.1kb when minified and gzipped.
Framer Motion is widely adopted and popular component libraries like Chakra UI use it to power their animations and transitions.
Framer Motion components and properties
While we cannot cover all the components and properties Framer Motion offers in this article, let’s explore the more important ones.
motion
module
At the core of Framer Motion is the motion module, a Document Object Model (DOM) primitive that gives us access to “motion” versions of HTML and SVG elements via dot notation. For example, we can have motion.div
, motion.h1
, and so on.
Motion elements work like their counterparts. The only difference is that we can apply animations to them via props. Here’s a sample of this in action:
import { motion } from "framer-motion" <motion.div animate={{ x: 100 }} />
I love Framer Motion because of its intuitive API. Even without explanation, you can probably tell what the code above does: it animates the div
by moving it along the x-axis by 100px
.
AnimatePresence
component
We can use AnimatePresence
to animate components as they enter and leave the DOM. A good application is to apply fade-in and fade-out animations to items in a todo list. We can also use it to add animations to a carousel.
Here’s an example of this in action if we had a modal on our page:
<AnimatePresence> {showModal && ( <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} > Modal content!!!! </motion.div> )} </AnimatePresence>
Based on the above effect, the modal div
will go through the following stages:
- Invisible at first
- Slowly becomes visible as the opacity increases to 1
- Slowly move back to stage 1 as the modal leaves the DOM
animate
prop
We’ve already seen a few examples of this. The animate
prop allows us to animate a component’s animatable properties.
We can use this prop to animate as many properties as needed. Note that the value of the x-axis is an array. That's because we are not restricted to a single animation. Instead, we can define a series of animations called keyframes. Framer Motion will animate each value in the keyframe in sequence.
<motion.div animate={{ x: [20, 50, 0, -70, 80, 100] y: 50, rotate: 30, opacity: 1 }} />
initial
prop
The initial
prop is where we define the initial state of a component. A good use case is when we want to position a component outside of the viewport and then animate it back into place:
<motion.div initial={{ x: -600px, scale: 0.6, opacity: 0 }} animate={{ x: 0, scale: 1, opacity: 1 }} />
transition
prop
The transition
prop is where we configure an animation’s behavior. Here are the animation properties we can configure:
- duration: sets the duration of an animation.
- type: specifies the type of animation. In this case, it's set to "spring", which means the animation will have a spring-like motion, mimicking real-world physics.
- ease: determines the easing function used for the animation transition. "easeInOut" refers to a curve that starts slowly, accelerates in the middle, and then decelerates towards the end, creating a smooth motion.
- stiffness: controls the stiffness or how sudden the movement animation is.
- bounce: determines the amount of bouncing or oscillation in the spring animation.
- damping: controls the damping or friction applied to the spring animation.
Here’s a sample code of the transition prop and its properties.
<motion.div animate={{ opacity: 1, x: 100, y: 100, rotate: 360 }} transition={{ duration: 0.25, type: "spring", ease: "easeInOut", stiffness: 500, bounce: 0.5, damping: 15 }} />
variants
prop
The variants
prop allows us to control the animation of elements between different states, like a burger menu in an open or closed state. It also allows us to control the animation of the element's children.
!embed Framer Motion - Variants
Here we have two states that the menu can be in "open", and "closed", which is applied to the animate
prop on the parent "menu" component. Using the variants
prop, we can now apply the desired animations to not only the parent element but all of its children. As you can see, we don't need to explicitly set the "closed" state for most cases. If a state is not supplied to the variant, the animation will be removed, i.e., we'll revert to the underlying CSS styles.
We also have control over the behavior of the child animations with the staggerChildren
and delayChildren
props:
stagerChildren
: This method incrementally delays the start of each child animation, allowing us to apply a stagger at the beginning of the child animations.delayChildren
: This delays the start of all child animations. It allows us to wait for the parent animation to finish before starting any child animations.
Variants can take some getting used to. However, they are a great feature of Framer Motion and give us more flexibility and control over animations.
Getting started with Framer Motion
Now that we have a basic understanding of how Framer Motion works, let’s explore how to integrate it into a React application. If you're not sure how to set up a React project, try using Vite. It's a great way to get up and running quickly with React.
Once the React project is set up, run the following command to install the framer-motion package:
npm i framer-motion
Building a hover animation with Framer Motion
With whileHover
, we can trigger an animation when the user hovers over an element. This is one of the gesture animations we can create with Framer Motion.
Try hovering over the square to see the animation.
As you can see whileHover
takes the same props as animate
, but will only apply the animation on hover.
Making animations accessible with useReducedMotion
While animations are great, depending on how extreme they are, they can negatively impact several groups of web visitors with conditions like:
- Vestibular disorders
- Seizures or epilepsy
- ADHD
- Low vision
- Cognitive disabilities
- Motion sickness
Thankfully, Framer Motion not only allows us to create animations but also provides a useReducedMotion
hook that we can use to make the animations accessible. useReducedMotion
checks if the user has enabled reduced motion on their device and returns a boolean value.
Here’s a snippet of useReducedMotion
in action:
import { useReducedMotion } from "framer-motion" function App() { const isAnimationDisabled = useReducedMotion(); return ( // animation disabled if the user has enabled reduced motion <motion.div animate={!isAnimationDisabled && { opacity: 1, rotate: 180, scale: 1.2 }} /> ) }
In this example, there will be no animation if reduced motion is active. However, if it’s not enabled, then the animation will run.
Want to learn more about accessibility and how to make your websites more accessible? You can take Frontend Mentor's "Introduction to web accessibility" learning path. I also wrote about 10 accessibility tips you can implement in future projects.
Further reading
Explore these resources to learn more about Framer Motion and making accessible animations:
- Framer Motion Documentation
- Creating Accessible UI Animations
- Designing With Reduced Motion For Motion Sensitivities
- Framer Motion for React Tutorial
Conclusion
Framer Motion makes creating animations in React applications straightforward. It provides the tools to animate components based on state changes, user interactions, scroll events, and more.
The tutorials we’ve covered should provide a solid starting point for adding eye-catching motion to your React projects.
Next steps
I challenge you to take everything you’ve learned so far and use Framer Motion to add animations and transitions to any Frontend Mentor challenge you’ve worked on.
Haven’t worked on any challenge yet? Then, now’s a good time to get started! I recommend starting with this FAQ accordion challenge. You can animate how the questions appear and disappear when users open and close them.
Practice building projects like a pro
- Portfolio-ready projects
- Professional design files
- Curate your profile
- Unlimited solution refinement