GitHub 22★

Clicking overlay

Modal is one of the common ways to display additional content on the page dynamically. It is often shown on top of an overlay that occupies the full screen.

In most cases, users can close the modal by either pressing the Escape key or clicking the overlay area. However, there are some situations in that we want to avoid that behavior.

For example, the modal contains important information that users can lose when it's closed by accident. I see that scaling the content a little bit is a common approach to let users know to pay more attention.

Click the overlay to see the effect

Demo

Layout

The modal including the overlay and its content is usually appended to the end of the page:

<body>
...

<div class="overlay">
<div class="content">...</div>
</div>
</body>

The overlay takes the full screen, hence it is positioned as a fixed element:

.overlay {
background: rgba(48, 64, 77, 0.6);

position: fixed;
left: 0;
top: 0;

/* Take the full size */
height: 100%;
width: 100%;
}

We also add an opacity value to the background allowing users to see the content behind it. In popular cases, the content is shown at the center of the overlay:

.overlay {
align-items: center;
display: flex;
}

Animation

Assume that the overlayEle and contentEle variables represent the overlay and content elements respectively. The following code handles the overlay's click event:

overlayEle.addEventListener('click', (e) => {
if (!contentEle.contains(e.target)) {
contentEle.classList.add('content--scale');
}
});

The .contains function checks if an element contains a given target. When users click the overlay, we need to check whether users click the overlay or content. If the check contentEle.contains(e.target) returns false meaning that users don't click the content, we append the content--scale class to it.

The class simply scales the content up to 1.2:

.content--scale {
transform: scale(1.2);
}

The animation can be activated if we add the transition property for the content element:

.content {
transition: transform 300ms ease-out;
}

After a given duration, 300ms in the sample code above, we have to scale the element down to its original size. To do that, we are going to handle the transitionend event:

contentEle.addEventListener('transitionend', (e) => {
if (e.target === contentEle) {
contentEle.classList.remove('content--scale');
}
});
Follow me on and to get more useful contents.