Building a simple React Modal
Tags: react, modal, frontend, css
Published: 2020-11-29 22:48:50

---
title: Building a simple React Modal
published: true
description: 
tags: #React, #Modal, #Frontend #CSS
//cover_image: https://direct_url_to_image.jpg
---

I have always used the react-modal package whenever I wanted to use a modal in a project but along the way, I wanted to build mine from scratch and it was so easy that I wondered why I resorted to the npm package. This will be a short article and very apt so come along.

First, Lets create two components; A home and a modal component for better comprehension. In the home component, lets have a simple h1 tag with a button and a function
```
import React, { Component } from 'react';
import './Home.css';
import Modal from './Modal';

class Home extends Component {
    state = {
        open: true
    };

    openModal = (e) => {
        e.preventDefault();
        this.setState({
            open: !this.state.open
        });
    };

    render() {
        return (
            <main>
                <section>
                    <h1>React-Modal</h1>
                    <button
                        onClick={(e) => {
                            this.openModal(e);
                        }}>
                        Open Modal
                    </button>
                </section>

                <Modal open={this.state.open} onClose={this.openModal} />
            </main>
        );
    }
}

export default Home;
```

and in the modal component, lets add same tags and a function too.

```
import React, { Component } from 'react';
import './Modal.css';

class Modal extends Component {
    onClose = (e) => {
        this.props.onClose && this.props.onClose(e);
    };

    render() {
        if (this.props.open) {
            return null;
        }

        return (
            <section className="modal-container" id="modal">
                <div className="modal-content">
                    <h1>Notify Me</h1>
                    <button onClick={this.onClose}>Close Modal</button>
                </div>
            </section>
        );
    }
}

export default Modal;
```

Let me explain a bit...We are setting our initial state to true and on click of the button, our state will be updated to false. Then we import the modal component which we created and pass a prop of open and onClose to it.

On the modal component, we got the passed prop and returns null if our state is true and the onClose function changes the state from true to false when close-modal button is clicked.

Now, if we run this code, we will see the raw structure but the modal isnt working yet so let's head over to CSS and design the magic.
```
/* -------------Home.css--------------------- */

*,
*::before,
*::after {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

main {
    text-align: center;
    padding-top: 20px;
}
```

```
/* -------------Modal.css--------------------- */
*,
*::before,
*::after {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

.modal-container {
	position: fixed;
	left: 0;
	top: 0;
	bottom: 0;
	height: 100%;
	width: 100%;
	overflow: hidden;
	z-index: 99;
	background-color: rgba(0, 0, 0, 0.5);
}

.modal-content {
	background-color: #f4f4f4;
	margin: 50px auto;
	width: 467px;
	height: 400px;
	max-width: 100%;
	max-height: 100%;
	border: 1px solid #ccc;
	padding: 40px 60px;
	box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.17);
}
```

and that is all...the modal-container is used as the background overlay to dim the home page while the modal-content is displayed on it. You can style your modal and even animate it to appear from top, left, bottom, fade in as you wish...lets do a little slide-down animation and call it a wrap

```
/* -------------Modal.css--------------------- */
.modal-content {
	background-color: #f4f4f4;
	margin: 50px auto;
	width: 467px;
	height: 400px;
	max-width: 100%;
	max-height: 100%;
	border: 1px solid #ccc;
	padding: 40px 60px;
	box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.17);
        animation: dropdwn ease-in-out 700ms;
}

@keyframes dropdwn {
	0% {
		opacity: 0;
		margin-top: -250px;
	}
	25% {
		opacity: 0.25;
		margin-top: -200px;
	}
	50% {
		opacity: 0.5;
		margin-top: -100px;
	}
	75% {
		opacity: 0.75;
		margin-top: -50px;
	}
	100% {
		opacity: 1;
		margin-top: 0px;
	}
}
```
and that is all...Ciao