8

I am building on a webpage template and made some modifications for modal pop up as given below:

<div class="modal fade" id="myModal4" tabindex="-1" role="dialog" style="background-color:#FECE1A;display:none;width:750px;left:46%" aria-hidden="true">
  <div class="modal-dialog">
  <script>
    $("#myModal4").on("show", function () {
      $("body").addClass("modal-open");
    }).on("hidden", function () {
      $("body").removeClass("modal-open")
    });
  </script>
  <!--Modal Content-->
  </div>
</div>

and the body.modal-open css function goes like this

body.modal-open {
  overflow: hidden;
}

the popup works fine. The problem is that whenever the pop up appears I can still click the header menu of the template and some links in the background. How do I disable everything in the background such that I can click only what is available at the popup.

James Douglas
  • 3,328
  • 2
  • 22
  • 43

3 Answers3

15

You could use an overlay - another div the full size of the screen that covers the html, with the bonus of giving a translucent grey shadow over the body.

In this example, use two divs.

One is the overlay, and the other (inside the overlay for convenience) is the modal.

<div class="overlay">
  <div class="modal">
    This is the modal. You can put whatever you like in here.
  </div>
</div>

Now the overlay needs styles:

.overlay {
  position: fixed; /* Positioning and size */
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(128,128,128,0.5); /* color */
  display: none; /* making it hidden by default */
}

and the modal needs some too:

.modal {
  position: fixed; /* positioning in center of page */
  top: 50vh;
  left: 50vw;
  transform: translate(-50%,-50%);
  height: 400px; /* size */
  width: 600px;
  background-color: white; /* background color */
}

Include jQuery by putting this:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

In the head tag at the top of your code.

Then, use this button to open the modal:

<button onclick="$('.overlay').show();">Open modal</button>

and this jQuery code to catch click on the overlay but not its child.

$('.overlay').on('click', function(e) {
  if (e.target !== this) {
    return;
  }
  $('.overlay').hide();
});

$('.overlay').on('click', function(e) {
  if (e.target !== this) {
    return;
  }
  $('.overlay').hide();
});
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(128,128,128,0.5);
  display: none;
}
.modal {
  position: fixed;
  top: 50vh;
  left: 50vw;
  transform: translate(-50%,-50%);
  height: 400px;
  width: 600px;
  background-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<a href="https://www.google.co.uk">This is a link, but with the modal open you can't click it!</a>
<br>
<br>
<button onclick="$('.overlay').show();">Open modal</button>

<div class="overlay">
  <div class="modal">
    This is the modal. You can put whatever you like in here.
  </div>
</div>
James Douglas
  • 3,328
  • 2
  • 22
  • 43
  • the code is working but i could not use it on my project, but it helped me a lot to solve the problem... thank you very much. –  Aug 10 '17 at 11:07
6

Introduction

A simple solution would be to add a <div> that covers the background, and is positioned below the popup but above all other content.

Below is a very simple example of what I would imagine you are trying to do. Hopefully you can adapt it to suit your scenario.

Example

function openModal() {
  $("#overlay").css({"display":"block"});
  $("#modal").css({"display":"block"});
}
#modal {
  position:fixed;
  left:50%;
  top:50%;
  transform:translate(-50%, -50%);
  border:solid 1px #000;
  display:none;
  background-color:#fff;
}

#overlay {
  position:fixed;
  left:0;
  top:0;
  width:100vw;
  height:100vh;
  display:none;
  background-color:#000;
  opacity:0.5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Awesome Content!

<button onclick="openModal()">Open Modal!</button>

<div id="overlay"></div>
<div id="modal"><h1>Modal Content!</h1></div>

Key Points

  • The #overlay div came before the #modal div - this is how I set the modal to be on top. Alternatively you could use z-index in CSS;

  • The opacity value is not required here, it is simply used as a demonstration of where the overlay is in relation to the page / modal;

  • None of the implementation details here matter. The JavaScript should not be important, neither should most of my CSS. The example simply exists to point you in the right direction.

Toastrackenigma
  • 7,604
  • 4
  • 45
  • 55
  • 1) your modal doesn't close 2) you don't need to set the height of body and html because you can use `width: 100vw;` (vw is viewport width. 100vw is 100% of the viewport width) and `height: 100vh;` (vh is viewport height) – James Douglas Aug 10 '17 at 08:44
  • @JamesDouglas My modal does not need to close - I am simply demonstrating how a background overlay would work, not how the Javascript would work (it is fairly simple). Thanks for reminding me about `vh` and `vw` though - I will edit my post to use these units instead. – Toastrackenigma Aug 10 '17 at 08:53
  • though it was not the solution, it helped to get an insight on the matter... thank you very much :) (y) –  Aug 10 '17 at 11:06
3

Here's an example of using CSS property pointer-events (https://developer.mozilla.org/en/docs/Web/CSS/pointer-events).

Example: https://codepen.io/zvona/pen/YxQzEO

The key idea is to have pointer-events: none; for the body when modal is open. But the specific elements you want to be interacted with should have e.g. pointer-events: auto;.

In the example you can click both buttons when dialog is hidden, but only Toggle Dialog button when dialog is shown.

Samuli Hakoniemi
  • 18,740
  • 1
  • 61
  • 74
  • 1
    This answer is cleaner than any others and should become the accepted answer. –  Jun 06 '20 at 15:02
  • Agreed that this answer appears cleaner, and easier, than the others. The others seem like more of a hack compared to this answer. – cag8f Jan 08 '21 at 05:49