Exit intent popups, those annoying little windows that appear when you try to close a browser window, can be easily implemented by listening to a specific DOM event. While I personally find them annoying, there may be cases where your company requires you to implement one. In this tutorial, I will show you a simple way to create an exit intent popup using HTML, CSS, and JavaScript.

Let’s start with the HTML structure for the popup:

<!doctype html>
<head>
 <title>Popup page</title>
</head>
<body>
 <div id="popup">
 <h3>Popup!</h3>
 </div>
</body>

Next, we’ll add some CSS styling to make the popup visually appealing:

body {
 font-family: system-ui;
 background-color: #f6d198;
}

#popup {
 position: fixed;
 width: 100%;
 visibility: hidden;
 z-index: 10002;
 top: 0;
 opacity: 0;
 transform: scale(0.5);
 transition: transform 0.2s, opacity 0.2s, visibility 0s 0.2s;
 position: relative;
 margin: 0 auto;
 text-align: center;
 box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
 width: 60%;
 background: #862a5c;
 padding-bottom: 100px;
 padding-top: 50px;
 color: #fff;
 font-size: 2rem;
}

Finally, let’s add the JavaScript code to control the popup:

const show = () => {
 const element = document.querySelector("#popup")
 element.style.visibility = "visible"
 element.style.opacity = "1"
 element.style.transform = "scale(1)"
 element.style.transition = "0.4s, opacity 0.4s"
}

document.addEventListener("DOMContentLoaded", () => {
 document.addEventListener("mouseout", (event) => {
 if (!event.toElement && !event.relatedTarget) {
 setTimeout(() => {
 show()
 }, 1000)
 }
 })
})

You can see the final implementation on CodePen here.

Once you load the page and move your mouse in and out, you should see the popup appearing after a second. The mouseout event is used to trigger the popup, and we added a delay of 1 second before showing it.

To enhance the functionality of the popup, you can add options to close it. For example, you can close the popup when the user presses the esc key:

const hide = () => {
 const element = document.querySelector("#popup")
 element.style.visibility = "hidden"
 element.style.opacity = "0"
 element.style.transform = "scale(0.5)"
 element.style.transition = "0.2s, opacity 0.2s, visibility 0s 0.2s"
}

document.addEventListener("DOMContentLoaded", () => {
 document.onkeydown = event => {
 event = event || window.event
 if (event.keyCode === 27) {
 hide()
 }
 }
})

You can also close the popup if the user clicks outside the modal:

let eventListener

//inside show()
eventListener = document.addEventListener("click", function (clickEvent) {
 let el = clickEvent.target
 let inPopup = false
 if (el.id === 'popup') {
 inPopup = true
 }
 while (el = el.parentNode) { 
 if (el.id == "popup") {
 inPopup = true
 }
 }
 if (!inPopup) hide()
})

//inside hide()
if (eventListener) {
 document.removeEventListener(eventListener)
}

You can see an example of these additional features on CodePen here.

To ensure that the popup is only shown once to each visitor, you can store that information in a cookie. By setting the popup=true cookie when the modal is shown and checking for its existence before showing it again, you can control the frequency of the popup:

let showed = false;

const show = () => {
 if (showed) return;

 if (
 document.cookie.split(";").filter((item) => {
 return item.includes("popup=");
 }).length
 ) {
 return;
 } else {
 console.log(
 document.cookie.split(";").filter((item) => {
 return item.includes("popup=")
 }).length
 )
 console.log(document.cookie.split(";"))
 }

 document.cookie = "popup=true;path=/;max-age=15768000"
 showed = true

 //...the remaining part of show()

By leveraging this cookie-based implementation, you can make sure that the exit intent popup is shown only once per user.

I hope you found this tutorial helpful in creating your own exit intent popup. Feel free to experiment and enhance the functionality as per your requirements.