← Back toCSS Animation

Clicking overlay

Written byPhuoc Nguyen
Created
29 Sep, 2022
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

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');
}
});

React example

Questions? 🙋

Do you have any questions? Not just about this specific post, but about any topic in front-end development that you'd like to learn more about? If so, feel free to send me a message on Twitter or send me an email. You can find them at the bottom of this page.
I have a long list of upcoming posts, but your questions or ideas for the next one will be my top priority. Let's learn together! Sharing knowledge is the best way to grow 🥷.

Recent posts ⚡

Newsletter 🔔

If you're into front-end technologies and you want to see more of the content I'm creating, then you might want to consider subscribing to my newsletter.
By subscribing, you'll be the first to know about new articles, products, and exclusive promotions.
Don't worry, I won't spam you. And if you ever change your mind, you can unsubscribe at any time.
Phước Nguyễn