Search code examples
javascripthtmlcssmodal-dialogecmascript-5

How to show overlay with pure JavaScript on modal?


I'm trying to make a modal with JavaScript ES5.

When you click a button, an overlay will show, and a modal window. The modal window will have an 'X' (close modal), which will remove the overlay and the modal. If you click the modal, nothing happens; if you click the X or overlay it hides.

I'm not sure what I'm doing wrong. I tried many things, however whenever I try to put my modal with the overlay the code stops working.

And do you see any way to improve the current code as well? Staying very basic.

// Click button
// Show overlay
// Show Modal - text and close button

// Click overlay - close
// Click button - close overlay
// Click modal - no effect

//Variables
var btn = document.querySelector('.btn-overlay');
var overlay = document.createElement = ('<div class="overlay"></div>');
var body = document.querySelector('body');
var modal = document.querySelector('.modal');
var closeBtn = document.querySelector('.modal-close');

function showModal(e) {
  e.preventDefault();
  modal.classList.add('is-active');
  document.body.appendChild(overlay);
}

function closeModal(e) {
  modal.classList.remove('is-active');
  document.body.removeChild(overlay);
}

btn.addEventListener('click', showModal);
closeBtn.addEventListener('click', closeModal);
.overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  height: 100%;
  width: 100%;
  z-index: 8000;
  background-color: rgba(0, 0, 0, 0.5);
}

.modal {
  background-color: red;
  display: none;
  position: absolute;
  top: 50%;
  right: 50%;
  bottom: 0;
  left: 0;
  z-index: 9000;
}

.modal.is-active {
  display: block;
}

.modal-close {
  position: relative;
  cusror: pointer;
  z-index: 9950;
}
<main>
  <h1>Awesome content</h1>
  <button class="btn-overlay"> Show Modal</button>
</main>

<section class="modal">
  <span class="modal-close">X</span>
  <h1>Modal</h1>
</section>

View on Codepen


Solution

  • You're not using document.createElement correctly. The method expects an argument—the type of element you wish to create.

    // Create a div
    var overlay = document.createElement('div');
    // Assign a class name
    overlay.className = 'overlay';
    

    Though this next bit wasn't breaking your code, you should fix the typo in your CSS:

    .modal-close {
      …
      cusror: pointer; /* <-- oops */
      …
    }
    

    Finally, you asked about suggestions to improve the code. I would read about how to make your modal code accessible. Accessibility is too often ignored when we make stuff and making your pixels work for everyone is critical. Have a look at this for examples and deep explanations. Apart from accessibility, I would consider adding a transition to your overlay and making it a pseudo element on the body. The advantage is cleaner code and less JavaScript.

    // Click button
      // Show overlay
      // Show Modal - text and close button
    
    // Click overlay - close
    // Click button - close overlay
    // Click modal - no effect
    
      //Variables
      var btn = document.querySelector('.btn-overlay');
      var overlay = document.createElement('div');
      overlay.className = 'overlay';
      var body = document.querySelector('body');
      var modal = document.querySelector('.modal');
      var closeBtn = document.querySelector('.modal-close');
      
    
      function showModal(e) {
        e.preventDefault();
        modal.classList.add('is-active');
        body.appendChild(overlay);
      }
    
      function closeModal(e) {
        modal.classList.remove('is-active');
        document.body.removeChild(overlay);
      }
      
      btn.addEventListener('click', showModal);
      closeBtn.addEventListener('click', closeModal);
                                 
    .overlay {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      height: 100%;
      width: 100%;
      z-index: 8000;
      background-color: rgba(0, 0, 0, 0.5);
    }
    
    .modal {
      background-color: red;
      display: none;
      position: absolute;
      top: 50%;
      right: 50%;
      bottom: 0;
      left: 0;
      z-index: 9000;
    }
    
    .modal.is-active {
      display: block;
    }
    
    .modal-close {
      position: relative;
      cursor: pointer;
      z-index: 9950;
    }
    <body>
    <main>
      
      <h1>Awesome content</h1>
      
      <button class="btn-overlay"> Show Modal</button>
      
      
    </main>
      
      <section class="modal">
        <span class="modal-close">X</span>
        <h1>Modal</h1>
      </section>
      
    </body>

    https://jsfiddle.net/y0wfzuj8/