DEV Community

Cover image for Make Pop-Up Modal Window In Vanilla JavaScript
Raja Tamil
Raja Tamil

Posted on • Originally published at softauthor.com

Make Pop-Up Modal Window In Vanilla JavaScript

alt text

Learn how to create a simple responsive pop-up modal window using Vanilla JavaScript along with HTML and CSS **with a bit of **Flexbox.

Create A Button That Opens Pop Up Modal Window

Declare a button HTML element with an id open-modal.

<button id="open-modal">Open Modal Window</button>
Enter fullscreen mode Exit fullscreen mode

The goal is when a user presses this button, the pop-up modal window will open.

Style the button using CSS Flexbox and centre it on the screen.

* {
    margin: 0;
    padding: 0;
    font-family: Arial, Helvetica, sans-serif;
    box-sizing: border-box;
}

body {
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

button {
    padding: 10px;
    font-size: 1.1em;
    background: #32bacf;
    color: white;
    border: none;
    border-radius: 10px;
    border: 1px solid rgba(0, 0, 0, 0.2);
    cursor: pointer;
}

button:hover {
    background: rgba(0, 0, 0, 0.7);
}
Enter fullscreen mode Exit fullscreen mode

alt text

Create Pop-Up Modal Overlay

Normally, pop-up modal windows have overlays with a transparent darker background that covers entire browser screen.

Define a div with an id model-overlay which will cover the entire screen.

<div id="modal-overlay">
<div>
Enter fullscreen mode Exit fullscreen mode

Then, make it to full screen using height:100vh CSS property.

Bring it in front of the button by using position:absolute with a transparent background colour.

#modal-overlay {
    width: 100%;
    height: 100vh;
    position: absolute;
    background: rgba(0, 0, 0, 0.7);
}
Enter fullscreen mode Exit fullscreen mode

I just added the border to see the boundaries of the modal-overlay element.

alt text

Center Pop-Up Modal Window To The Modal Overlay

Create a div with an id modal inside the modal-overlay element, which will be an actually pop-up modal window that user interacts with.

<div id="modal-overlay">
  <div id="modal">
  </div>
<div>
Enter fullscreen mode Exit fullscreen mode

Add CSS style to make it visible on the screen.

Adding width:100% and max-width:650px will make sure the width of the pop-up modal window won’t exceed when the browser width is more than 650px.

If the browser width is less than 650px, the pop-up modal window will stretch the width to fill the screen which is normally for mobile viewports.

#modal-overlay #modal {
    max-width: 650px;
    width: 100%;
    background: white;
    height: 400px;
}
Enter fullscreen mode Exit fullscreen mode

alt text

Centre the pop-up modal window to the screen using Flexbox.

To do that, just add the three lines of Flexbox code to the modal-overlay which are:

  • display:flex → Convert an HTML element to Flexbox
  • align-items:center → centre the pop-up modal window vertically to the viewport
  • justify-content:center → centre the pop-up modal window horizontally to the viewport
#modal-overlay {
   ...

   display: flex;
   align-items: center;
   justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

alt text

Open Up Pop-Up Modal Window On Button Click

Now we have the basic pop-up modal window designed using CSS.

Make it visible when a user presses the open modal button.

To do that,

First, hide the modal overlay by default by changing its display property from flex to none.

#modal-overlay {
   ...

   display: none; // Changed from flex to none
   align-items: center;
   justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

Create a DOM reference to the open-modal button as well as the modal-overlay elements.

const openModalButton = document.getElementById("open-modal");
const modalWindowOverlay = document.getElementById("modal-overlay");
Enter fullscreen mode Exit fullscreen mode

Attach a click event to the openModalButton with the callback arrow function showModalWindow.

const showModalWindow = () => {
    modalWindowOverlay.style.display = 'flex';
}

openModalButton.addEventListener("click", showModalWindow);
Enter fullscreen mode Exit fullscreen mode

Set the display property of the modalWindowOverlay to flex inside showModalWindow() function which will open up the modal window.

alt text

As you can see, there is no way we can close/hide the pop-up modal window after its became visible on the screen.

Let’s fix it!

Close/Hide Pop-Up Modal Window On Button Click

Typically, there will be a close button on the top or bottom right side of the pop-up modal window.

Let’s add a close button on the bottom left side of the modal window.

Define header, content and footer HTML elements inside the pop-up modal window.

<div id="modal">

    <div class="modal-header">
        <h2>Modal Pop Up Window</h2>
    </div>

    <div class="modal-content">
        <p>Modal Content</p>
    </div>

    <div class="modal-footer">
        <button id="close-modal">Close</button>
        <button>Save</button>
    </div>

</div>
Enter fullscreen mode Exit fullscreen mode

Generally, you’ll have two buttons on the footer of the pop-up modal window, which may be save and close.

alt text

Let’s push the buttons to the bottom using Flexbox.

Turn the display property of the pop-up modal window to flex and set the flex direction to column.

Set margin-top to auto to the .modal-footer element which pushes the buttons to the bottom.

#modal-overlay #modal {
    max-width: 650px;
    width: 100%;
    background: white;
    height: 400px;

    display: flex;
    flex-direction: column;
    padding:10px;
}

#modal-overlay #modal .modal-footer {
    margin-top: auto;
}

Enter fullscreen mode Exit fullscreen mode

alt text

Let’s hide the pop-up modal window when the user presses the close button.

Define a DOM reference of the close button.

Attach a click event to the close button with the call back function hideModalWindow.

Declare hideModalWindow function and set the display property of modalWindowOverlay to none inside it.

const closeModalButton = document.getElementById("close-modal");

const hideModalWindow = () => {
    modalWindowOverlay.style.display = 'none';
}

closeModalButton.addEventListener("click", hideModalWindow);
Enter fullscreen mode Exit fullscreen mode

alt text

Hide Pop-Up Modal Window When Modal Overlay Is Clicked

In addition to the close button, you often see the pop-up modal window will be closed or hidden when the user clicks away from it.

To do that, we need to identify if a user clicks the actual pop-up modal window and its content inside or the modal overlay that covers the entire screen.

To check that,

Attach a click event to the #modal-overlay with a callback function hideModalWindowOnBlur.

modalWindowOverlay.addEventListener("click", hideModalWindowOnBlur)
Enter fullscreen mode Exit fullscreen mode

Using e.target and e.currentTarget properties of an event object we can identify where a user clicks when the pop-up modal window is visible on the screen.

e.target will capture a clicked HTML element which can be either the parent or child elements.

The parent element will be referred to an element that has a click event attached to.

In this case, the #modal-overlay.

The child elements will be referred to all the HTML elements right inside the parent element.

On the other hand, e.currentTarget will only get the parent element regardless of where user clicks either parent or child elements.

In this case the #modal-overlay.

This way we can determine whether a user clicks the #modal-overlay or the actual pop-up modal window.

If a user presses the modal overlay, hide/close it by checking if e.target value is equal to e.currentTarget.

const hideModalWindowOnBlur = (e) => {

    if(e.target === e.currentTarget) {
        hideModalWindow();
    }
}

Enter fullscreen mode Exit fullscreen mode

alt text

If you’ve any questions or suggestions about this article, feel free to reach out to me by commenting below and I’ll read and reply to each and every one of them.

I’m looking forward to hearing from you.

Happy coding…

Top comments (3)

Collapse
 
frankwisniewski profile image
Frank Wisniewski

You could also use the dialog element

<!DOCTYPE html>
<html lang=en>
<meta charset=UTF-8>
<title>Document</title>
<h1>Test Dialog</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perspiciatis cumque suscipit quisquam quod molestiae rem maxime repellendus voluptatum nesciunt laborum, explicabo consequatur, nostrum in minus. Id dolorem tempora accusantium perferendis!</p>
<button id=openDialog>show Dialog</button>
<dialog id=myDialog>
  <article>
   <header><h2>mydialog</h2></header>
   <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure sit beatae nisi nemo eaque minus ipsa culpa. Vel voluptates, et quibusdam quas nesciunt unde labore alias eveniet cumque fuga? Quod.
   <footer>
     <button id=closeDialog>close</button>
   </footer>
  </article> 
</dialog>
<script>  
  openDialog.addEventListener('click', ()=> myDialog.showModal())
  closeDialog.addEventListener('click', ()=> myDialog.close())
</script>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
amabe_dev profile image
amabe_dev

Nice article as an exercise to touch to multiple concepts with both CSS and JavaScript.

I agree, the dialog option seems easier now that it is supported by browsers though.

For anyone reading that is interested in more details about this, I found this article from @dailydevtips1 great:

Also there is an accessibility issue that is easy to make: forget to capture the focus. When a modal is opened, we should not be able to focus elements that are outside the modal. I think your example has this problem.

Collapse
 
nickperry profile image
Nick Perry • Edited

Recently did for a small website, for New Year's discounts.

<div id="popup" class="popup">
        <div class="popup-content">
            <span class="close">&times;</span>
            <h2>New Year Special Offer!</h2>
            <p>Enjoy a 40% discount on all our products!</p>
            <div id="timer">
                <p>Time Left:</p>
                <span id="days"></span> days
                <span id="hours"></span> hours
                <span id="minutes"></span> minutes
                <span id="seconds"></span> seconds
            </div>
        </div>
    </div>
Enter fullscreen mode Exit fullscreen mode

CSS

.popup {
    display: none;
    position: fixed;
    z-index: 1;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto;
    background-color: rgba(0,0,0,0.4);
    text-align: center;
}

.popup-content {
    background-color: #fefefe;
    margin: 15% auto;
    padding: 20px;
    border: 1px solid #888;
    width: 50%;
}

.close {
    color: #aaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
}

.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}

#timer {
    font-size: 20px;
    margin-top: 20px;
}
Enter fullscreen mode Exit fullscreen mode

JS

```document.addEventListener("DOMContentLoaded", function() {
var popup = document.getElementById("popup");
var close = document.getElementsByClassName("close")[0];

// Display the popup
popup.style.display = "block";

// Close the popup
close.onclick = function() {
    popup.style.display = "none";
}

// Click outside to close
window.onclick = function(event) {
    if (event.target === popup) {
        popup.style.display = "none";
    }
}

// Set the date we're counting down to
var countDownDate = new Date("Jan 1, 2024 00:00:00").getTime();

// Update the count down every 1 second
var x = setInterval(function() {

    // Get today's date and time
    var now = new Date().getTime();

    // Find the distance between now and the count down date
    var distance = countDownDate - now;

    // Time calculations for days, hours, minutes and seconds
    var days = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((distance % (1000 * 60)) / 1000);

    // Display the result in the elements with id="days", id="hours", id="minutes" and id="seconds"
    document.getElementById("days").innerHTML = days;
    document.getElementById("hours").innerHTML = hours;
    document.getElementById("minutes").innerHTML = minutes;
    document.getElementById("seconds").innerHTML = seconds;

    // If the count down is finished, write some text 
    if (distance < 0) {
        clearInterval(x);
        document.getElementById("timer").innerHTML = "EXPIRED";
    }
}, 1000);
Enter fullscreen mode Exit fullscreen mode

});```

But as for me, it's easier to find a ready-made beautiful template, adapt it and put it on the site. It will take much less time. Here here took a template for myself claspo.io/ not a bad choice.