Modals are a great way to present critical information or user interactions without leaving the current page. In this blog, I’ll show you how to create a custom modal popup using the react-modal library and styled-components in React.
Step 1: Setting Up the React Project
First, you need to install the required dependencies:
npm create vite@latest
npm i react-modal
npm i styled-components
Step 2: Creating the Custom Modal Component
Here’s the full implementation of a custom modal component using react-modal and styled-components.
DefaultModal.jsx
// Import Libraries import React, { useState } from 'react'; import styled, { createGlobalStyle } from 'styled-components'; import ReactModal from 'react-modal'; // CSS-in-JS const GlobalStyle = createGlobalStyle` .ReactModal__Overlay { background-color: rgba(88,79,79,.788) !important; opacity: 0; display: flex; justify-content: center; align-items: center; transform: translateY(-10px); transition: all 500ms ease-in-out; } .ReactModal__Overlay--after-open { opacity: 1; transform: scale(1); overflow-y: auto; z-index: 99999 !important; } .ReactModal__Overlay--before-close { opacity: 0; transform: translateY(0px); } `; const ModalWrapper = styled(ReactModal)` position: relative; width: 552px; min-height: 200px; background: #fff; border: 1px solid #ccc; margin: 0 auto; border-radius: 10px; outline: none; overflow: hidden; transform: scale(1); animation: slide 0.5s forwards 0.5s; @keyframes slide { 100% { right: 0; } } `; const CloseImg = styled.div` position: absolute; right: 15px; top: 12px; padding: 10px; border-radius: 50px; height: 35px; width: 35px; &:hover { cursor: pointer; background-color: #e3f2ff; border-radius: 50px; } `; const MainWrapper = styled.div` padding: 20px; `; const Title = styled.h1` font-size: 20px; margin-top: 0; color: #454545; `; const Text = styled.p` font-family: inherit; color: #454545; font-size: 14px; margin-top: 20px; `; const DefaultModal = (props) => { const [isOpen, setisOpen] = useState(true); const handleClose = () => { setisOpen(false); }; return ( <div> <GlobalStyle /> <ModalWrapper isOpen={isOpen} onRequestClose={() => handleClose()}> <CloseImg onClick={() => handleClose()}> <svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg" > <path d="M9.59008 8.14771L16.1632 1.82104C16.311 1.65502 16.3882 1.44146 16.3794 1.22304C16.3706 1.00462 16.2766 0.797433 16.116 0.642873C15.9554 0.488313 15.7401 0.397767 15.5132 0.38933C15.2863 0.380893 15.0644 0.455188 14.8919 0.597365L8.31873 6.92404L1.74557 0.588687C1.57308 0.446509 1.3512 0.372216 1.12427 0.380652C0.89734 0.389089 0.682077 0.479634 0.521495 0.634194C0.360912 0.788755 0.266839 0.995946 0.258074 1.21436C0.249308 1.43278 0.326497 1.64634 0.474214 1.81236L7.04738 8.14771L0.465197 14.4744C0.370809 14.5522 0.294149 14.6479 0.240028 14.7556C0.185907 14.8633 0.155493 14.9805 0.150696 15.1001C0.1459 15.2196 0.166824 15.3388 0.212155 15.4501C0.257486 15.5615 0.326246 15.6626 0.414118 15.7472C0.501989 15.8318 0.607076 15.898 0.722783 15.9416C0.83849 15.9852 0.962318 16.0054 1.0865 16.0008C1.21067 15.9961 1.33252 15.9669 1.44438 15.9148C1.55625 15.8627 1.65572 15.7889 1.73655 15.6981L8.31873 9.37139L14.8919 15.6981C15.0644 15.8402 15.2863 15.9145 15.5132 15.9061C15.7401 15.8977 15.9554 15.8071 16.116 15.6526C16.2766 15.498 16.3706 15.2908 16.3794 15.0724C16.3882 14.854 16.311 14.6404 16.1632 14.4744L9.59008 8.14771Z" fill="#352960" /> </svg> </CloseImg> <MainWrapper> <Title>Default modal title</Title> <Text> Lorem ipsum odor amet, consectetuer adipiscing elit. Risus convallis cras. Nibh congue. Risus vitae nam maximus. Vel fames mi nec. Habitasse turpis felis. </Text> </MainWrapper> </ModalWrapper> </div> ); }; export default DefaultModal;
App.jsx
import DefaultModal from "./DefaultModal"; export default function App() { return ( <> <DefaultModal /> </> ); }
Understanding the Code
- GlobalStyle for Animations: The
createGlobalStyle
function from styled-components is used to customize the animation of the modal’s overlay. It defines how the modal will appear and disappear on the screen. - Modal Styling: We use styled-components to style the ReactModal component. The
ModalWrapper
defines the size, background, and the animation for when the modal opens. - Close Button: The close button is a styled div, and an SVG is used to represent the close icon.
- Modal Content: Inside the modal, there’s a title and a paragraph of text. These elements are styled using styled-components for consistency and customization.
Output:

Conclusion
This tutorial demonstrates how to build a custom modal using react-modal and styled-components in React. The approach allows you to create a reusable, customizable modal with transitions and styles that align with your app’s design.
You can check the full documentation of the react-modal library here.
Add comment