The Ultimate Guide for Creating a Simple Modal Component in Vanilla JavaScript, React, Angular…

14,481 reads

Recently, I left my job position at Microsoft, and re-joined Outbrain.

Moving between companies isn’t always easy, as there’s not necessarily a consistency between technologies and libraries each company uses for developing their front end projects. For example, at Microsoft we used React for our projects, and in Outbrain the most common framework is Angular.

No matter which framework or libraries you’re going to develop with, product’s specs and requirements for developing web apps will mostly remain the same, so you’ll probably end up creating the same components for different libraries over and over again.

One of the most common component in web apps is the (mighty) Modal. In this article I’ll work you through how to create a simple modal component with vanilla JavaScript, as well as with each one of the 3 most popular JavaScript libraries & frameworks: React, Angular, and Vue.

Take a deep breath, we’re going in.

BTW, if you don’t have 10 minutes to read the whole article, you may find the Github repository with all of the examples here:

Spec

Before we start creating a modal component, we need to understand its core concepts and requirements.

Modal is an element that appears and disappears after an event occurred on a page (page loaded, click, scroll, etc.).

Modal should support all kinds of content including text, images, videos.

Modal should be responsive and fit all kind of screen dimensions.

Traditionally, a modal will have two layers: an overlay (for hiding the page’s content), and the modal itself.

Modal should have a default design, but support custom classes for customizing the design of specific elements.

Modal should have a close button.

The modal controller should be notify on modal events (such as modal opened, modal closed, etc).

Just to complete the spec, here’s an example of a modal for composing a new tweet in Twitter:

Basics

Although we’re going to implement our modal in 4 different JavaScript libraries and methods, we could use the same basic CSS and HTML for mocking our modal.

The HTML:

As you may see, the HTML code is pretty straightforward. We have a wrapper div element with the class modal , and it has 2 children:

overlay — this element will be in the background, and will be responsible for hiding the content of our web app.

— this element will be in the background, and will be responsible for hiding the content of our web app. modal_content — this element is the modal itself, and will include the modal’s content.

The CSS (where the magic actually happen 🎩):

First, we set a position: fixed; for the modal’s wrapper element (the one with the .modal class). In addition, we’ll make sure it takes 100% of our viewport’s width and height by setting width: 100%; height: 100%; . We’ll also align it to the top-left corner of the screen with left: 0; top: 0; . This will ensure that our modal is getting all of the attention as other parts of the screen won’t be interactive.

Next, we need to create a nice and a bit transparent overlay layer. We’ll set an absolute position for the .overlay div, and stretch it over the viewport with the same technique we used for the .modal element. Then, we’ll add a black background color with a transparency to element, in order to get the effect we want (line 17).

Last, we need to design the modal itself by adding styles to the .modal_content div element. In order to make sure it’s always aligned to the center of our viewport, we’ll set an absolute position and add left: 50%; top: 50%; alignment. In addition, we’ll add transform: translate(-50%, -50%); which will ensure that the modal will always be aligned to the center without any dependency on the width and height of the modal. Another technique we’ll use is to set a max-height of 90% to the modal element, and make sure that if the content is higher than that the browser will add scrollbars — overflow: auto; (line 27).

The background color, and the rest of the properties are up to you. I used a white background, added a border-radius some padding and a default width.

Here’s the result:

Ladies & gentlemen we’ve got a modal!

Coming up next: make it functional.

Modal in Vanilla JS

If we look at the spec, the first requirement of a modal is to be able to appear and disappear on demand, or to be more accurate, when an event occurred on a web page. For the sake of this tutorial, we’ll open the modal once a user clicks a specific button.

So first, let’s create a button:

<button id="modal_opener">Click Me! I Don't Bite... 😛</button>

Then, we’ll add the modal’s HTML from our basic example and change the content:

Note that the modal display is set to none as we don’t want the modal to appear on page loads.

We’ll import a style.css file that will contain our page & modal CSS (again, from the “basics” part of this tutorial).

And finally, we’ll create a script called modal.js to handle the functionality.

You should end up with the following HTML:

After adding some styles to the page, I managed to get the following result:

Now for the interesting part.

Here’s how modal.js will look like:

What’s going on here?

First, we created 2 variables for holding the DOM elements we’ll work with:

btn — will hold the button that triggers the appearance of the modal (line 1).

— will hold the button that triggers the appearance of the modal (line 1). modal — will hold the modal element itself (line 2).

Then we’ll add 3 different functions:

toggleModal — the main function. It will check what’s the current state of the modal by looking at the modal.style.display property (line 18). If the value is none it will set the value to block so the modal will be visible (line 19), and attach events for closing the modal (line 20). Otherwise, if the modal is visible, it will set the value to none and will detach the closing events (line 23).

— the main function. It will check what’s the current state of the modal by looking at the property (line 18). If the value is it will set the value to so the modal will be visible (line 19), and attach events for closing the modal (line 20). Otherwise, if the modal is visible, it will set the value to and will detach the closing events (line 23). attachModalListeners — will add 2 event listeners for closing the modal. One on clicking the .overlay layer, and the other one on clicking the .close_modal element.

— will add 2 event listeners for closing the modal. One on clicking the layer, and the other one on clicking the element. detachModalListeners — will remove the event handlers from the 2 elements we mentioned above.

The final part will be to add the event handler itself when clicking the button:

btn.addEventListener('click', toggleModal); (line 27)

That’s it! You got yourself a nice modal in Vanilla JS:

Modal in React

In React, developing a reusable component is by design. So creating our modal component is going to be easy.

For simplicity we’ll generate a new app with create-react-app .

Then, we’ll work on 2 main components:

app.js — our app’s main component that will contain the button that triggers the modal opening, and will import the modal component.

— our app’s main component that will contain the button that triggers the modal opening, and will import the modal component. modal.js — the reusable modal component.

After creating a modal folder and files, the structure of our project will look as follows:

React’s “src” folder after creating a modal folder and component.

Let’s take a look at the modal component ( modal.js ):

Let’s see what we have here.

First, in lines 1–4, we imported all relevant dependencies including the modal component’s CSS (which I copied from previous examples).

Then we created a stateless component that accepts 4 properties:

children — this argument will be a placeholder for the dynamic content section of our modal. It will be replaced by the content we’ll append to the modal component.

— this argument will be a placeholder for the dynamic content section of our modal. It will be replaced by the content we’ll append to the modal component. show — a boolean value that will determine if the modal should be visible or hidden.

— a boolean value that will determine if the modal should be visible or hidden. closeCallback — a callback function that will be called once a user clicks on either the close button or the overlay layer.

— a callback function that will be called once a user clicks on either the close button or the overlay layer. customClass — if we set a custom class to the modal component, it will be chained to the modal’s container. This will help us to customize the modal content if needed.

All properties are optional and have a default value (lines 25–30).

Now that we have the modal component ready, it’s time to use it.

In the app.js we imported the modal component (line 3).

The app component’s state contains a boolean property called showModal (line 9). This property will be responsible for the modal visibility. In addition, we added a toggleModal method (line 12) that, as the name suggests, will toggle the modal’s visibility on and off.

The render method will include 2 elements:

A button element, with an onClick method that will call the toggleModal once clicked and will open the modal (lines 21–23).

method that will call the once clicked and will open the modal (lines 21–23). A modal component with the relevant properties (lines 25–29), and a children element that will be used as the modal content (lines 30–33).

And… There you go. A modal component in React!

Modal in Angular

It’s funny. I’m not new to Angular, in fact, I spent most of my career developing with both AngularJS and Angular, and still, implementing the modal with Angular took me the longest, and I found myself keep confusing with Angular annotations for data binding.

Anyway…

We’ll generate a new Angular app using the Angular CLI, and run the ng new modal-app command.

Next, we’ll add a new component called “modal” by running ng generator c modal .

Just for a reference, this is how our src folder will look like:

Angular’s “src” folder after generating a modal component.

Let’s start with the app.component.ts file:

Pretty simple right?

The AppComponent has a showModal property for determine whether the modal should be opened or not. In addition, it has a toggleModal method that will toggle the showModal property from true to false in both ways.

Next, let’s take a look at the modal.component.ts file:

The modal component accepting 3 inputs:

show — a boolean value for showing / hiding the modal.

— a boolean value for showing / hiding the modal. customClass — an optional string that will be chained to the .modal class in order to style a specific modal.

— an optional string that will be chained to the class in order to style a specific modal. closeCallback — a function that responsible for closing the modal.

We’ll use those 3 inputs in the modal.component.html template:

In line 1 we’ll add dynamically the custom class by using [ngClass] , and will set the display property to block if the show property is set to true , and to none if it’s set to false .

In lines 2 & 5 we’re attaching the closeCallback method on a click event, and in line 4 we’re transcluding the modal content.

And here’s how we’re adding the modal to the app.component.html file:

Note that the name of the component is app-modal which being set in the modal.component.ts file under the selector property.

Modal in Vue

We’ll start by installing Vue CLI and generating a new Vue app by running vue create modal-app .

Next, under the components folder we’ll create a new Vue file for our modal component.

The src folder of our app should look like this:

Vue’s “src” folder after creating a modal component.

Let’s take a look at the App.vue file:

In line 16 we created a script tag. In this script we’ll first import the modal component (line 17), and then export the Vue object with our configuration.

In the components property we declare the Modal component (line 21) so our template will be able to use it. In line 25 we’ll add the show property with a boolean value to our data object, and in line 28 we’ll add the toggleModal method that will be responsible to toggle the show property value from true and false and vice versa.

The <template> section includes a button element (line 3) with a Vue event listener v-on:click that will call the toggleModal method on click event, as well as a Modal element that binds 3 attributes (line 8):

show — a boolean value for determine if the modal is opened or not.

— a boolean value for determine if the modal is opened or not. closeCallback — a callback function that being called after a user clicks the close button.

— a callback function that being called after a user clicks the close button. customClass — a string that will be added to the modal wrapper element for style customization.

You probably wondering how the modal component will look like in Vue, so here it is:

We define a template that includes our modal’s HTML.

A few things to notice:

Line 2: We’re adding the custom class by using the v-bind:class annotation, and changing the CSS display property by using the v-bind:style and change its value from block to none if the show property is being set to true or false accordingly.

annotation, and changing the CSS property by using the and change its value from to if the property is being set to or accordingly. Line 3 & 6: In order to use the closeCallback method, we use the @click annotation.

method, we use the annotation. Line 5: The <slot></slot> tag will be used for transcluding the modal content.

Next, we’re exporting a Vue object with the name Modal (line 14), and setting the types of each one of the props we want to support (line 16).

And you’re all done!

A side note: this was the first time I wrote a web app with Vue, and it took me less time than Angular & React (which I’m well familiar with) 😌. So to sum up my first experience with Vue:

Wrapping up

Although each library and framework has its own syntax and annotations, the concept remains the same.

Once we understood the technique behind the creation of a simple modal component in Vanilla JavaScript, it was easy enough to implement it with React, Vue, and Angular.

By the way, in HTML 5 there’s a dialog element with some nice native API that allows custom styling, and although there are a few ready-to-use polyfills, most of the browsers still don’t support it.

The Github repo with all of the examples is available below:

If you liked this article, feel free to share, clap, like, read again, send to your friends, and read it to your children before bed time 🙂

Tags