Exit Intent Popup: A Guide to Creating an Engaging Modal

As internet users, we can all admit that popups are not our favorite thing. Most of us never click on them and often leave the page when we encounter them. However, there’s no denying that popups are effective. They convert users to your goal better than most other techniques. In fact, on my developer portfolio, resume downloads increased from zero to ten within the first week of implementing an exit intent modal.

The job market is competitive, and I personally know how it feels when it seems like no one is looking at your resume. That’s why I’ve created this tutorial—to help you get your resume into the hands of a real person. It also has the added bonus of showcasing your expertise in creating effective popups that convert.

In this article, we’ll dive into the step-by-step process of building an on exit intent JavaScript modal, similar to the one shown below. If you’ve been following me, you might have noticed my fondness for creating gaming-inspired web elements, like my SNES controller nav bar.

Exit Intent Modal

What are Exit Intent Modals (Popups)?

Exit intent modals are a type of popup that use JavaScript to detect when a user is about to leave a webpage. When triggered, they display a popup box. Normally, this popup is triggered by a JavaScript event, such as the user’s mouse moving off the document, onto the address bar, or off the browser entirely.

However, most exit intent modals can be quite intrusive and annoying for users. In this tutorial, we’ll make sure our modal is less disruptive and more delightful for users to stumble upon. We’ll also ensure that they only see it once, as seeing the same modal multiple times can be extremely irritating.

So, let’s dive into the step-by-step tutorial for creating this exit intent modal using HTML, CSS, and JavaScript.

Project Setup

To get started, I’ve set up a GitHub repository with all the necessary start files for this project. Feel free to fork the project here.

First, let’s quickly understand what’s happening with the HTML for this project. On line 3, we’ve created a container for our modal and given it the ID of “onExitModal”. This is important because we’ll be targeting this container with JavaScript later on.

Next, we create a container for our modal content. The modal content container is divided into three sections: our message, icons, and resume. The message section is split word by word using span elements, allowing us to animate each word individually with CSS.

Finally, the first span element contains an “x” symbol, which allows the user to easily and intuitively close the modal. Implementing this functionality will require some JavaScript.

With just the HTML, your modal should look something like the example below:

<!-- Modal Container -->
<div id="onExitModal">
  <!-- Modal Content Container -->
  <div class="modalContent">
    <!-- Message Container -->
    <div class="messageContainer">
      <span>As</span>
      <span>you</span>
      <span>know,</span>
      <span>the</span>
      <span>job</span>
      <span>market</span>
      <span>is</span>
      <span>competitive.</span>
      <!-- Other content omitted for brevity -->
    </div>
    <!-- Close Button -->
    <span class="close">✕</span>
  </div>
</div>

As you can see, our modal is hidden on the page until the user performs the exit intent action. Therefore, we need to implement some CSS to hide the modal. Let’s take a look at how to do that.

Adding the CSS

The CSS for this project can be divided into three key parts: functional CSS, styling CSS, and animations.

The functional CSS

First, let’s ensure that the modal is hidden from the user’s view. Add the following code to your CSS file:

#onExitModal {
  display: none;
  position: fixed;
  z-index: 99;
}

In the code above, the display: none property ensures that the modal is hidden by default. Next, we set the position of the modal to fixed, which keeps it in the same place on the page even if the user scrolls up and down. Lastly, we set the z-index to 99 to ensure that the modal appears in front of all other elements on the page.

See also  JavaScript Course: A Comprehensive Syllabus

With these CSS styles in place, the modal will be hidden from the user’s view. Now, let’s move on to styling the rest of the modal to make it visually appealing. We’ll start with the modalContent container.

The Styling CSS

The styling CSS is pretty straightforward. However, you’ll need to adjust the width for different screen sizes, as well as the size of the content (images, text, link). Here’s an example of the styling CSS:

.modalContent {
  /* Styling properties omitted for brevity */
}

Now that the modalContent container is styled, let’s move on to styling the close button.

.close {
  /* Styling properties omitted for brevity */
}

With the CSS code above, the “x” symbol will appear on the right side of the modal, and when hovered over, it will change color to indicate to the user that they can close the modal.

Next, we’ll style the font in our message section.

.messageContainer {
  /* Styling properties omitted for brevity */
}

We’re using the Google font ‘Press Start 2P,’ so make sure to add the following code to the <head> section of your HTML:

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Press+Start+2P&display=swap">

After that, we’ll style the images in the icon container, as they are currently too big and throw off the alignment of our exit intent modal.

.iconContainer img {
  /* Styling properties omitted for brevity */
}

We can apply an effect to the images using the filter property and the CSS drop-shadow function. This creates a nice shadow effect on the images. Please note that this method only works with transparent images.

Lastly, we need to style the resume link and the sword element.

.resumeContainer {
  /* Styling properties omitted for brevity */
}

.sword {
  /* Styling properties omitted for brevity */
}

In the code above, we’ve placed both elements in a flex container so that we can position them in the center and in a column formation.

That’s it for the styling of our exit intent modal. Now, let’s add the JavaScript functionality to show the modal when the user is about to exit the page.

Exit Intent Modal JavaScript

Now that we have the basic CSS set up to hide the modal from the user’s view, let’s add some JavaScript code to determine when to show the modal. To connect the modal.js file to your HTML, place the following line of code within the body tags at the very bottom of your HTML file:

<script src="modal.js"></script>

With the files connected, we can start writing our exit intent modal JavaScript code to make the modal appear when a user goes to exit the page. Add the following code to your modal.js file:

document.addEventListener('mouseout', exitEvent);

function exitEvent(e) {
  if (!e.toElement && !e.relatedTarget) {
    document.getElementById('onExitModal').style.display = 'block';
  }
}

In the code above, we’ve added a mouseout event listener to the document. This event is fired when the user’s mouse is moved outside the document, indicating that they are trying to exit the page.

Next, we perform a conditional check to ensure that there is no toElement and relatedTarget. These two properties retrieve the element that the mouse pointer entered. If they are null, it means that the mouse is no longer on any element on the page, indicating that the user is trying to exit.

Finally, we select the modal using getElementById and change its display property from none to block, making it appear on the screen to the user.

Great! Now you have a working exit intent modal. However, it’s not perfect, as the modal will appear every time the user moves the mouse. This can get annoying. Let’s optimize it by ensuring that the modal shows only once per session and adding other functionality to improve the user’s experience.

See also  A/B Testing in JavaScript: The Ultimate Guide

Optimizing the Exit Intent Modal JavaScript

To ensure that the modal is shown only once per session, let’s make some changes to the event listener in our JavaScript code:

let exitListener = document.addEventListener('mouseout', exitEvent);

function exitEvent(e) {
  if (!e.toElement && !e.relatedTarget) {
    document.getElementById('onExitModal').style.display = 'block';
    document.removeEventListener('mouseout', exitListener);
  }
}

function setCookie(name, value, days) {
  // Cookie implementation omitted for brevity
}

function getCookie(name) {
  // Cookie implementation omitted for brevity
}

if (!getCookie('resumeModalSeen')) {
  let exitListener = document.addEventListener('mouseout', exitEvent);
  setCookie('resumeModalSeen', true, 7);
}

In the code above, we’ve wrapped our event listener in a conditional statement. This checks if there is no cookie named ‘resumeModalSeen’, and if true, listens for the mouseout event.

We then call the setCookie function within the exitEvent function once the modal has been seen. This prevents the user from seeing the modal for one week.

Please note that there are laws and guidelines regarding cookies, particularly the GDPR guidelines. If you implement a modal like this, make sure you are compliant with the regulations.

By adding cookies and converting the event listener to a function, we’ve solved the issue of the modal appearing multiple times. Next, we want to ensure that the user has spent some time on our page before the modal appears. We don’t want the modal to appear if a user is on our page for just a second and then goes to exit.

To handle this, we’ll wrap our event listener in a setTimeout method. This way, the modal will only appear after the user has been on the page for a certain amount of time.

setTimeout(() => {
  let exitListener = document.addEventListener('mouseout', exitEvent);
}, 6000);

In the code above, we ensure that the event listener is only attached to the DOM after the user has been on the page for 6 seconds. This gives enough time for the user to explore the page without being immediately bombarded by the modal.

Next, we want to optimize the exit intent by ensuring that it only shows when the user moves their mouse to the top of the browser. We’ll make this adjustment in our exitEvent function.

function exitEvent(e) {
  if (!e.toElement && !e.relatedTarget && e.clientY < 5) {
    document.getElementById('onExitModal').style.display = 'block';
    document.removeEventListener('mouseout', exitListener);
  }
}

In the code above, we’ve added the e.clientY < 5 condition to check the vertical position of the mouse cursor. If the position is less than 5, we can safely assume that the user has moved the mouse towards the top of the browser and not to the left, right, or bottom.

Now, our modal will appear exactly as we want it to. But we need to provide the user with a way to close the modal. Let’s add that functionality.

Closing the Modal

To make the user experience less annoying, it’s important to provide a clear way for users to exit the modal. We’ll provide two ways for the user to close the modal: by clicking on the close button and by clicking anywhere outside the modal.

First, let’s add the following code to the modal.js file to handle the close button functionality:

document.querySelector('.close').addEventListener('click', function() {
  document.getElementById('onExitModal').style.display = 'none';
});

In the code above, we’ve added an onclick event handler to the close button. When the user clicks on the “x” symbol in the modal, the display property is set to none, making the modal appear closed.

Next, to allow the user to close the modal by clicking anywhere outside the modal content, add the following code:

document.getElementById('onExitModal').addEventListener('click', function(e) {
  if (e.target === this) {
    document.getElementById('onExitModal').style.display = 'none';
  }
});

In the code above, we’ve added another onclick event handler. This time, we’re checking if the user clicks on the modal content itself (anything within the gray border). If the user clicks outside of the content and on the onExitModal element, the modal will close.

And there you have it! Your exit intent modal is complete. Well done!

To add some extra flair and really grab the user’s attention before they leave the page without downloading your resume, let’s add some CSS animations.

See also  JavaScript SMS: Enhancing Customer Interaction and Engagement

Adding CSS Animations

Animating the exit intent modal is the fun part, and I encourage you to experiment with different animations to make it your own. If you’re not familiar with CSS animations, you can find resources online to get started. In this article, I’ll show you how to implement animations without going into too much explanation.

In this case, we’ll use two different animations. First, we’ll animate the text to appear word by word, reminiscent of old video games. Then, we’ll animate the resume and sword to appear, similar to how they appeared in some Zelda games.

Animating Text Word by Word with CSS

To animate the text word by word, we’ll utilize the fact that each word is wrapped in a separate <span> element. We’ll use the .fadeIn class to animate each of these spans. First, let’s add the animation to our CSS:

.messageContainer .fadeIn span {
  opacity: 0;
  animation: textFadeIn 0.5s linear forwards;
  animation-delay: 0.3s;
}

In the code above, we’re using a combination selector to select all <span> elements within the parent with the class .fadeIn. We set the opacity to 0, making the spans invisible but still retaining their position on the modal. Then, we add the textFadeIn animation, which lasts for 0.5 seconds, has a smooth linear timing function, and keeps the final styles applied using the animation-fill-mode property. Finally, we add a delay of 300 milliseconds to ensure that the animation doesn’t start as soon as the modal opens.

Now that the animation is attached to the elements, we need to define the actual animation. Here’s an example:

@keyframes textFadeIn {
  0% {
    opacity: 0;
    transform: translateX(-100px);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

In the code above, at the start of the animation, the text has 10% opacity and is positioned -100px on the x-axis. As the animation progresses, the opacity increases to 100% and the position moves towards 0, creating the effect of the text appearing on the modal.

However, this animation will make all the words appear at once. To make them appear word by word, we need to target each <span> element and add an animation-delay. Here’s an example:

.messageContainer .fadeIn span:nth-child(2) {
  animation-delay: 0.4s;
}

.messageContainer .fadeIn span:nth-child(3) {
  animation-delay: 0.5s;
}

/* Add styles for other spans */

In the code above, we’re targeting the second <span> element and giving it a delay value that is 100ms before the end of the previous element’s animation. This creates a flowing effect for the text.

Now, the text should flow much better. Let’s move on to animating the resume container to float up.

Animating a Container to Float Up

First, add the following CSS to the resumeContainer styling:

.resumeContainer {
  opacity: 0;
  animation: resumeUp 0.5s forwards;
  animation-delay: 3.5s;
}

In the code above, we’ve set the opacity to 0, making the container invisible at the start. Then, we add the resumeUp animation, which lasts for 0.5 seconds and retains the final styles applied. We also add a delay of 3.5 seconds, which is approximately the time it takes for the text animation to finish. This creates a nice timing so the resume appears just after the text “take this”. It gives the impression that the user is being offered the resume.

Now, let’s define the resumeUp animation:

@keyframes resumeUp {
  0% {
    opacity: 0;
    transform: translateY(100px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

In the code above, we set the opacity to 0 and position the container 100px below its original position at the start of the animation. As the animation progresses, the opacity increases, and the container moves towards its original position, creating the floating up effect.

And there you have it! You’ve successfully created an engaging exit intent modal using HTML, CSS, and JavaScript to boost your resume downloads.

Remember, while this modal is live on my portfolio, I encourage you to create your own unique modal instead of copying mine. Add some personal flair that matches your own style! Feel free to play around with it on this CodePen.

Now, go ahead and implement this exit intent modal on your website to capture the attention of users and increase your resume downloads. Good luck!


This article was created for ProgramMatek.