Creating Animated Modals in React

Loading

Modals are a common UI element in web applications, used to display additional content or options without navigating away from the current page. Adding animations to modals can greatly improve the user experience by making the transitions feel smoother and more dynamic. In this guide, we’ll walk through how to create animated modals in React, using Framer Motion for the animations.

1. Setting Up the Project

First, make sure you have a React project. If you don’t have one already, you can create it using create-react-app:

npx create-react-app animated-modals
cd animated-modals

Now, install Framer Motion for animation support:

npm install framer-motion

2. Basic Structure of a Modal in React

A modal in React typically consists of three main parts:

  • A modal container (which covers the screen).
  • The modal content (which holds the modal’s content).
  • A close button (to dismiss the modal).

Here’s a basic modal component without animation:

import React, { useState } from 'react';

const Modal = ({ isOpen, onClose }) => {
  if (!isOpen) return null;

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal-content" onClick={(e) => e.stopPropagation()}>
        <h2>Modal Title</h2>
        <p>This is some content inside the modal!</p>
        <button onClick={onClose}>Close</button>
      </div>
    </div>
  );
};

const App = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const openModal = () => setIsModalOpen(true);
  const closeModal = () => setIsModalOpen(false);

  return (
    <div>
      <button onClick={openModal}>Open Modal</button>
      <Modal isOpen={isModalOpen} onClose={closeModal} />
    </div>
  );
};

export default App;

In this basic example:

  • The Modal component is conditionally rendered based on the isOpen prop.
  • Clicking on the overlay or the close button triggers the onClose function to close the modal.

3. Adding Framer Motion Animations

Now, let’s enhance the modal with animations using Framer Motion. We’ll animate the modal’s appearance (fade in and scale up) when it opens, and make it fade out when it closes.

Update the Modal Component:

import React from 'react';
import { motion } from 'framer-motion';

const Modal = ({ isOpen, onClose }) => {
  if (!isOpen) return null;

  return (
    <motion.div
      className="modal-overlay"
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      transition={{ duration: 0.3 }}
      onClick={onClose}
    >
      <motion.div
        className="modal-content"
        initial={{ scale: 0.8 }}
        animate={{ scale: 1 }}
        exit={{ scale: 0.8 }}
        transition={{ duration: 0.3 }}
        onClick={(e) => e.stopPropagation()}
      >
        <h2>Modal Title</h2>
        <p>This is some content inside the modal!</p>
        <button onClick={onClose}>Close</button>
      </motion.div>
    </motion.div>
  );
};

export default Modal;

Explanation of Animation:

  • motion.div: We use motion.div from Framer Motion to animate both the modal overlay and content.
  • initial, animate, exit: These are Framer Motion’s animation states.
    • initial defines the starting state when the modal appears.
    • animate defines the final state when the modal is fully visible.
    • exit defines the state when the modal is removed (during closing).
  • transition: This controls the duration and easing of the animations.

4. Adding Styling

Let’s style the modal so it looks better.

/* App.css */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}

.modal-content {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.2);
  max-width: 500px;
  width: 100%;
}

button {
  padding: 10px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}

5. Animating Modal Close Action

Next, let’s handle the close animation. We want the modal to fade and scale down when it’s closed. We’ve already defined the exit animation for the modal content in the Modal component. However, we also need to make sure that the modal closes smoothly when the user clicks outside the modal or presses the close button.

Since we’ve already defined the exit state for the modal content, Framer Motion will handle the exit animation for us. By wrapping the modal content and overlay in motion.div, it will automatically trigger the exit animation when the modal is removed from the DOM.

6. Final Code

import React, { useState } from 'react';
import Modal from './Modal';
import './App.css';

const App = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const openModal = () => setIsModalOpen(true);
  const closeModal = () => setIsModalOpen(false);

  return (
    <div>
      <button onClick={openModal}>Open Modal</button>
      <Modal isOpen={isModalOpen} onClose={closeModal} />
    </div>
  );
};

export default App;

Leave a Reply

Your email address will not be published. Required fields are marked *