This CAPAHILL tutorial is the technical breakdown of how I built my first modal. In my previous blog post I expressed the difficulty I faced as a new coder trying to solve this problem. Let’s get into how I really managed to achieve this with the use of JavaScript. (This modal was built with the help of Foundation and jQuery)

To begin, I created a simple button in my HTML doc that would open the modal when clicked.

Next I created the modal itself.

HTML:

<div class="modal-overlay" id="modal-overlay"></div>

<div class="modal-wrapper" id="modal-wrapper">
    <div class="modal" id="modal">
      	<button class="close-button" id="close-button"><h5></h5></button>
      	<div class="modal-guts">
            <div class="row details">
                <div class="column">
            	    <p>This is the modal</p>
          	</div>
            </div>
        </div>
    </div>
</div>

As you can see above, I created a close button with the X Unicode character (). I built it so that when the user clicked on the open button my modal would pop up above my website and when the user clicked the X my modal would close. I also added an overlay that would darken the main part of my website so that the modal would stand out. Next up I added some CSS to make my modal look a little bit prettier.

CSS:

body.modal-open {
    overflow: hidden;
}

.modal-wrapper {
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    z-index: 200;
    padding: 60px;
    overflow-y: auto;
    display: none;
}

.modal {
    display: none;
    width: 600px;
    position: relative;
    margin: auto;
    background: #fff;
    box-shadow: 0 0 60px 10px rgba(0, 0, 0, 0.9);
}

.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 50;
    background: rgba(0, 0, 0, 0.6);
    display: none;
}

.modal-guts {
    padding: 35px;
    color: #1c1b1b;
}

.modal .close-button {
    position: absolute;
    z-index: 1;
    top: 15px;
    right: 15px;
    color: inherit;
    padding: 1px 11px 2px 12px;
    border-radius: 25px;
}

.modal .close-button h5 {
  margin: 0;
}

.modal .close-button:hover {
    background-color: #353336;
    color: #fff;
    transition: .2s;
    cursor: pointer;
}

.open-button {
    border: solid 1.5px #38e5c5;
    color: #38e5c5;
    padding: 15px 20px 10px 20px;
    margin-top: 60px;
}

.open-button:hover {
    background-color: #38e5c5;
    color: #fff;
    cursor: pointer;
    transition: .3s;
}

Here I styled the fonts, colours, hover attributes, and spacing. It is important to note that the modal wrapper is centered with position: fixed and the modal itself has display: none and position: relative. This allows the modal to be positioned within the modal wrapper constraints and to remain invisible until the user clicks the open button. I also enabled the ability to scroll the modal within the modal wrapper setting the property to overflow-y: auto.

Now I needed to add some jQuery in my JavaScript file to activate the click events.

JAVASCRIPT / JQUERY:

var closeButton = document.querySelector("#close-button");
var openButton = document.querySelector("#open-button");

closeButton.addEventListener("click", function() {
    $("#modal").hide();
    $("#modal").scrollTop();
    $("#modal-overlay").hide();
    $("#modal-wrapper").hide();
    $("body").removeClass("modal-open");
});

openButton.addEventListener("click", function() {
    $("#modal").show();
    $("#modal-overlay").show();
    $("#modal-wrapper").show();
    $("body").addClass("modal-open");
});

I started by creating a variable for each button for the modal. Then I added an event listener with a click function to both these buttons. Here I used .show() and .hide() to enable the modal to pop up and disappear. I added a .scrollTop() method to the close button so that the modal would always start at the top of the window. As you can see I also added .addClass()/.removeClass() to the body. This class added the attribute overflow: hidden to the body which made it possible for the user to scroll only on the modal.

As I mentioned before, up until this point, the modal was moderately easy to build as I was already familiar with these jQuery methods. Now I was faced with the challenge of understanding what method to use so that my modal would close when the user clicks outside of the modal itself.

MORE JAVASCRIPT / JQUERY:

window.addEventListener(“mouseup”, function(event) {
    if (!$(event.target).closest(".modal,.open-button").length) {
        $("#modal").hide();
        $("#modal").scrollTop();
        $("#modal-overlay").hide();
        $("#modal-wrapper").hide();
        $("body").removeClass("modal-open");
    }
});

After research and many other online tutorials – I came to this conclusion. I began with an event listener placed on the window that used a mouseup function. This means the JavaScript file can understand anytime the user simply clicks on the window. After that I knew I had to differentiate between these clicks to find which ones were happening precisely when the modal was open and the clicks were outside of the modal itself. Sounds confusing right?

I realized I had to use an if statement to tell the JavaScript file in a logical way that only some of these clicks are useful to this specific function and others are not. My if statement essentially says “if the recordable click is not from the modal, the things inside the modal, or the close button on the modal, then do this…”. The ! before the function checks to see if it is NOT from the listed parameters. The .closest() method searches through the elements (in my case the modal and the open button) and their ancestors to create a new object from the matching elements. This new object is used in combination with the .length() method which allows the mouseup function to differentiate whether the click is happening inside or outside the whole “length” of the modal.

Finally, I had to tell the modal what to do if this click was indeed from outside the modal. This part was relatively straight forward as the methods listed within the if statement are the same methods attached to the close button.

And that was it! Easy, right? If you’re a visual person like me and need a more hands on example, check out this CodePen. I know that feeling of staring into your code trying to find the solution and thinking “it’s impossible”, but, after this task I truthfully felt like JavaScript and I were finally becoming friends. Over coming a difficult task like this proves that coding isn’t that hard, it just takes a little bit of practice and sometimes, many cups of coffee.