← Back toCSS animation

Clicking overlay

Written byPhuoc Nguyen
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


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

<div class="overlay">
<div class="content">...</div>
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;


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)) {
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) {

React example

If you found this post helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

Questions? 🙋

Do you have any questions about front-end development? If so, feel free to create a new issue on GitHub using the button below. I'm happy to help with any topic you'd like to learn more about, even beyond what's covered in this post.
While I have a long list of upcoming topics, I'm always eager to prioritize your questions and ideas for future content. Let's learn and grow together! Sharing knowledge is the best way to elevate ourselves 🥷.
Ask me questions

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