Tips for hiding a modal when clicking outside of it

function openModal(){
        document.getElementById("overlay").style.display='block';
        document.getElementById("modal").style.display='block';
    }
        function closeModal(){
        document.getElementById("overlay").style.display='none';
        document.getElementById("modal").style.display='none';
    }
.closex{
             border: none;
            background-color: transparent;
             font-weight: bold;
        }
        .open{
             border: none;
            background-color: dodgerblue;
            border-radius: 14px;
            width: 150px;
            height: 40px;
            font-size: 20px;
    }
        body{
            background-color: whitesmoke;
        }
        .modal{
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    transition: 200ms ease-in-out;
    border-radius: 10px;
    z-index: 10;
    background-color: white;
    width: 500px;
    max-width: 80%;
    font-family: Arial;
    border: 1px solid white;
    box-shadow: 0 60px 120px rgba(0, 0, 0, 0.14), 0 40px 160px rgba(0, 0, 0, 0.24);
   -webkit-animation: animatezoom 0.6s;
  animation: animatezoom 0.6s;
        }

@-webkit-keyframes animatezoom {
  from {-webkit-transform: translate(-50%,-50%) scale(0)} 
  to {-webkit-transform: translate(-50%,-50%) scale(1)}
}
  
@keyframes animatezoom {
  from {transform: translate(-50%,-50%) scale(0)} 
  to {transform: translate(-50%,-50%) scale(1)}
}

        .mhead{
            border-bottom: 1px solid rgba(0,0,0,0.5);
            padding: 15px 15px 15px;
            font-size: 22px;
        }
        .mbody{
            padding: 15px 15px 15px 15px;
            font-size: 19px
        }
        .close{
            margin-left: 330px;
        }
        #overlay{
             display: none;
    position: fixed;
        top: 0;
    left: 0;
    right: 0;
    bottom: 0;
background-color: rgba(0,0,0,0.5);
    pointer-events: none;
        }
<body>
        <div id="overlay"></div>
        <div class="modal" id="modal">
            <div class="mhead">Welcome!!!<span class="close"><button class="closex" onclick="closeModal()">&times;</button></span></div>
            <div class="mbody">
            Welcome to this site! We are very happy that you are using this site. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec odio et eros accumsan pulvinar. Integer tristique nulla eu sapien consectetur, sed auctor est consequat. Proin ac lectus in nisi porta mollis at non mauris. Etiam tincidunt vestibulum risus, vel laoreet libero blandit eget.
                </div>
        </div>
        <div align="center">
    <button onclick="openModal()" class="open">Open Modal</button>
            </div>
    </body>

Having trouble making the modal disappear when clicking outside of it? Here's a code snippet to achieve that:

var modal = document.getElementById('modal');

// Close the modal when clicked outside of it
window.onclick = function(event) {
    if (event.target == modal) {
        modal.style.display = "none";
    }
}

If you've tried other solutions without success, give this code a shot!

Answer №1

All the puzzle pieces are in your hands, you just need to connect them. Remove the pointer-events: none; from the overlay CSS so it can be clickable. Then, add onclick="modalclose()" to your overlay. That's all that is needed.

function modalopen(){
        document.getElementById("overlay").style.display='block';
        document.getElementById("modal").style.display='block';
    }
        function modalclose(){
        document.getElementById("overlay").style.display='none';
        document.getElementById("modal").style.display='none';
    }
.closex{
             border: none;
            background-color: transparent;
             font-weight: bold;
        }
        .open{
             border: none;
            background-color: dodgerblue;
            border-radius: 14px;
            width: 150px;
            height: 40px;
            font-size: 20px;
    }
        body{
            background-color: whitesmoke;
        }
        .modal{
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    transition: 200ms ease-in-out;
    border-radius: 10px;
    z-index: 10;
    background-color: white;
    width: 500px;
    max-width: 80%;
    font-family: Arial;
    border: 1px solid white;
    box-shadow: 0 60px 120px rgba(0, 0, 0, 0.14), 0 40px 160px rgba(0, 0, 0, 0.24);
   -webkit-animation: animatezoom 0.6s;
  animation: animatezoom 0.6s;
        }

@-webkit-keyframes animatezoom {
  from {-webkit-transform: translate(-50%,-50%) scale(0)} 
  to {-webkit-transform: translate(-50%,-50%) scale(1)}
}
  
@keyframes animatezoom {
  from {transform: translate(-50%,-50%) scale(0)} 
  to {transform: translate(-50%,-50%) scale(1)}
}

        .mhead{
            border-bottom: 1px solid rgba(0,0,0,0.5);
            padding: 15px 15px 15px;
            font-size: 22px;
        }
        .mbody{
            padding: 15px 15px 15px 15px;
            font-size: 19px
        }
        .close{
            margin-left: 330px;
        }
        #overlay{
             display: none;
    position: fixed;
        top: 0;
    left: 0;
    right: 0;
    bottom: 0;
background-color: rgba(0,0,0,0.5);
        }
<body>
        <div id="overlay" onclick="modalclose()"></div>
        <div class="modal" id="modal">
            <div class="mhead">Welcome!!!<span class="close"><button class="closex" onclick="modalclose()">&times;</button></span></div>
            <div class="mbody">
            Welcome to this site! We're thrilled that you're using our platform. It integrates various functions for each user to enjoy. If you want to explore more, feel free to dive into different features and functionalities available on the site.
                </div>
        </div>
        <div align="center">
    <button onclick="modalopen()" class="open">Open Modal</button>
            </div>
    </body>

Answer №2

If you're wondering where the click is happening, this code can help:

    window.addEventListener("click", function(e) {
      if (document.getElementById("modalWindow").contains(e.target)) {
        alert("The click happened inside");
      } else {
        alert("The click happened outside");
      }
    });

Answer №3

Modals are quite straightforward by design. A basic setup typically includes the modal itself, a close button (which can be inside or outside the modal), and a backdrop.

example of a basic modal setup

Now, the goal is to close the modal when either the backdrop or the close button is clicked. There is a specific design choice to make here - you can nest the modal inside the backdrop, or keep them at the same level in the DOM. Based on your example, it seems like you chose the latter option. In this scenario, all you have to do is add an onClick event to the backdrop.

<div id="overlay" onclick="modalclose()"></div>

If you were to have the modal within the backdrop, you would also need to prevent event propagation, as any click within the modal would trigger the onClick events of its parent elements (including the backdrop).

var modalElement = document.getElementById('modal');
modalElement.addEventListener('click', function(event){ 
    event.stopPropagation();
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to troubleshoot Props not functioning in nextjs-typescript?

I'm having trouble with props in my project and I can't seem to figure it out! Here are the three files. I'm still learning typescript but everything seems fine in the code, yet it's not working! Here is index.tsx file: const Home: ...

Uncovering the secrets of incorporating axios with Vue in Typescript

I'm facing difficulties while trying to incorporate axios into my Vue project using Typescript. Below is a snippet of my main.ts file: import axios from 'axios' Vue.prototype.$axios = axios axios.defaults.baseURL = 'http://192.168.1.22 ...

What is the significance of Fawn's statement, "Invalid Condition"?

Despite following the instructions and initiating Fawn as stated in the document, I'm still encountering an error message that says Invalid Condition. Can anyone help me identify what is causing this issue? Thank you to all the helpers. await new Fawn ...

Uncovering Inline Styles Infused with Javascript for Effective Debugging of Javascript Code

SITUATION: I have recently inherited a website from the previous developer who has scattered important functions across numerous lengthy JS files. I am struggling to track down the source of an inline CSS style within the JS or identify which function is d ...

Express Session Issue Preventing Ajax Call from Functioning

After testing the /temp route directly in the browser and then through an ajax call to the /test route, I noticed a difference in the session information. When accessed directly, the session retains the data added via the /temp route, but when called throu ...

Confirming the truthfulness of a function while inside the execution of an asynchronous function

After submitting a form, I receive JSON as a response. My objective is to only submit the form if the received json.ok value is true. $("form").submit(function() { var _this = $(this); // send request to server, validate json, if ok return true $.getJSON( ...

CSS auto width not applied to images causing a lack of scaling

I recently added this code to my webpage: image { margin: 0 2px 0 0; height: 100px; width: auto !important; overflow: hidden; text-align: center; } The goal was to scale all images to a maximum height of 100px and have the browser adj ...

Utilize @db.Decimal within the Prisma framework for the parameters "s", "e", and "d"

When I define the schema in Prisma like this: value Decimal? @db.Decimal(7, 4) Why do I always get this format when retrieving the value from the database: "value": { "s": 1, "e": 0, & ...

Troubleshooting the problem of divs overlapping when scrolling in JavaScript

I am experiencing some issues with full screen divs that overlay each other on scroll and a background image. When scrolling back to the top in Chrome, the background shifts down slightly, and in Safari, the same issue occurs when scrolling down. I have cr ...

most effective method for recycling dynamic content within Jquery mobile

My jQuery mobile app has a requirement to reuse the same content while keeping track of user selections each time it is displayed. I have successfully created the necessary html content and can append it to the page seamlessly. The process goes something ...

What is the best method for integrating addEventListener with Javascript functions located in a different file?

I currently have document.addEventListener('DOMContentLoaded', functionName); which uses the function below: function functionName() { $.ajax({ type: 'GET', url: '/populatePage', success: function(data) { ...

inject spinner during the call and verify status post-call

How can I make the loading icon display during the save function call and then switch to the check mark icon after the function resolves instead of mocking it on a timeout? function save() { successMessage() new Promise((resolve, reject) => { setTim ...

Enhancing user experience by implementing dynamic text box functionality that triggers ajax load for dropdown options using a combination

Here is the task I need help with, along with the code snippet: I want to enable the author select box when both the start and end dates are filled out. The author names should be fetched dynamically from the database based on the selected start and end ...

Adjust the appearance depending on the React state variable

I am trying to add animation to a search icon when clicked in React. Using the useRef hook, I am able to access the element and applying custom styles to it. const [searchBar, setSearchBar ] = useState(false); const searchIcon = useRef(); const searchIconS ...

Ways to retrieve live data from vuex state directly into a component

I am currently delving into the world of Vuex, but I believe there are some fundamental concepts that I may be missing. Any suggestions or insights would be greatly appreciated. Currently, I am dispatching the scale value of a zoomable map from one compon ...

Creating a Kendo Grid that mimics the appearance and functionality of an

Can someone help me with styling my Kendo grid to match the look of a basic HTML table? I want to use the table style I already have set up instead of the default Kendo style. Is there a way to achieve this? #resultTable th { cursor:pointer; } #result ...

Unable to access properties after utilizing the map function

In my React app, I have a structure where the main "app.js" file sets the state and passes props to the "ThumbnailAreas" component. In "ThumbnailAreas", I utilize the map function to distribute these props to individual "ThumbnailArea" components. Each "Th ...

I'm currently working on developing a CPS tester, but have encountered a few challenges along the way

All of the text remains aligned to the left, despite my attempts to position it at the top. I feel like I haven't even completed 1% of the task and I'm faced with countless issues. Although I've coded it so that every click should incremen ...

I'm having trouble importing sqlite3 and knex-js into my Electron React application

Whenever I try to import sqlite3 to test my database connection, I encounter an error. Upon inspecting the development tools, I came across the following error message: Uncaught ReferenceError: require is not defined at Object.path (external "path ...

Transforming an element into a buffer using JavaScript

Utilizing Plain JavaScript for Data Transfer in Web Workers In my current project, I am avoiding the use of Node and sticking to plain JavaScript within the browser. One challenge I encountered is efficiently sending data to web workers. After some experi ...