How to make a zoom effect using CSS

Written by Web Developer

February 3, 2023
How to make a zoom effect using CSS

In this article, we will cover a famous effect used in e-commerce websites: Zooming over images. We will see how to achieve such an effect using CSS and with the smallest amount of code possible. We will end with an interactive demo at the end. Let’s go!

The zoom effect combines two things. Making the image bigger and then hiding part of it. The idea is to keep the same area of the initial image while zooming over a portion of it. To make the image bigger we will logically use a scale transformation but for the “hiding part” we have different methods.

Using Overflow: hidden


The first and easy method is to consider overflow: hidden and to do this we need an extra container for the image so our code will look like the below:

<div class="container">
 <img src="" alt="" >
</div>

Here is a demo to illustrate the idea:

As you can see, the code is pretty straightforward:

.container {
  display: inline-grid;
  overflow: hidden;
}
img {
  transform: scale(1.5);
  transform-origin: 40% 20%;
} 

The scale transformation on the image and overflow: hidden on the parent. Note the use of transform-origin that control the point of zoom. The value used with transform-origin is the coordinate of the point that will be in the center of the container. In other words, we will zoom around that point.

Why the use of display: inline-grid?

It’s not part of the feature but inline-grid allows me to make the width of the container as wide as the image (thanks to the inline- part) and at the same time to avoid the white space at the bottom of the image (thanks to the -grid part).

If you hover the over above images you can see the untrimmed version (without overflow: hidden).

50%

💰 50% OFF YOUR FIRST MONTH ON MANAGED CLOUD SERVERS

with the discount code

SERVERS-SALE

Use Code Now

Using clip-path


What about doing the same thing without the container? Yes, it’s possible! Since our goal is to hide some part of the image after the scale transformation we can rely on clip-path or mask to do the job. clip-path will be more suitable here with the inset() value:

The inset() CSS function is one of the <basic-shape> data types. It defines an inset rectangle. ref

Our code will look like below:

img {
  transform: scale(1.5);
  transform-origin: 40% 20%;
  clip-path: inset(???);
} 

Only three properties are needed for our zoom effect applied to a single image element but finding the value of clip-path is a bit tricky. The value will depend on the other values so we are going to define CSS variables:

img {
  --zoom: 1; /* control the zoom level */
  /* the coordinate of the zoom */
  --x: 50%;
  --y: 50%;
  /**/
  transform: scale(var(--zoom));
  transform-origin: var(--x) var(--y);
  clip-path: inset(???);
}

And here is a figure to better understand the values and the calculation we need to perform:

Overview of the clip path values

The yellow point illustrates the value of the transform-origin. Note that this point is at the center of the red rectangle after performing the scale transform. We need to hide what is outside the red rectangle so the inset() value needs to define a rectangle with the same position/size as the red rectangle shown above.

The figure illustrates the left value of inset(). X is the value we defined using --x and X' is the scaled value of X. Their difference represents the offset we are looking for. It’s important to notice that we divide the result with the zoom value because the second image is scaled so we need that division to find the real value and not the scaled one.

We do the same logic with the other sides and we get the following:

img {
  --zoom: 1; /* control the zoom level */
  /* the coordinate of the zoom */
  --x: 50%;
  --y: 50%;
  /**/
  transform: scale(var(--zoom));
  transform-origin: var(--x) var(--y);
  clip-path: inset(
    calc((1 - 1/var(--zoom)) * (var(--y)))
    calc((1 - 1/var(--zoom)) * (100% - var(--x)))
    calc((1 - 1/var(--zoom)) * (100% - var(--y)))
    calc((1 - 1/var(--zoom)) * (var(--x)))
  );
}

It may look a bit complex but thanks to the CSS variables all you need to do is to update a few values to control the zoom effect. You don’t have to touch the value of inset()

Here is the final demo to illustrate the trick.

An Interactive Demo


Now that we have our zoom effect, we are going to make it interactive by introducing a little bit of JavaScript.

But you said CSS-only?

Yes, and it’s still true. The zoom effect relies on pure CSS but the JavaScript will simply update a few variables to make it interactive.

Here is a demo. Hover over the image to see the magic effect!

Cool right? We did the zoom feature of e-commerce websites with a little CSS code, a few lines of JS, and a single HTML element. No complex markup and no external library!

The JavaScript consists of a simple listener that updates the --x and --y variables with the mouse position.

20%

💸 EXTRA 20% OFF ALL VERPEX RESELLER HOSTING PLANS

with the discount code

AWESOME

Save Now

Conclusion


I hope after that you will no more struggle to create a zoom effect. You don’t need a lot of funky code or complex libraries to achieve it. Here is again the full code you need to create a cool zoom effect easy to control.

HTML

<img src="" alt="">

CSS

img {
  /* the coordinate of the zoom */
  --x: 50%;
  --y: 50%;
  /**/
  transform: scale(var(--zoom));
  transform-origin: var(--x) var(--y);
  clip-path: inset(
    calc((1 - 1/var(--zoom)) * (var(--y)))
    calc((1 - 1/var(--zoom)) * (100% - var(--x)))
    calc((1 - 1/var(--zoom)) * (100% - var(--y)))
    calc((1 - 1/var(--zoom)) * (var(--x)))
  );
  width: 200px;
  cursor: crosshair;
}

JavaScript (optional)

let img = document.querySelector("img");

img.onmousemove = function(e) {
  e.target.style.setProperty('--x',(100*e.offsetX/e.target.offsetWidth)+'%');
  e.target.style.setProperty('--y',(100*e.offsetY/e.target.offsetHeight)+'%'); 
}

Frequently Asked Questions

How do I get migrated to Verpex?

The migration process is as easy as you can imagine! Regardless of how many websites you’re managing, we’ll bring all of them under the Verpex wing free of charge. Just send us the details of your websites when you’ve signed up to get started.

Are website builders easy to use?

One of the easiest ways to build a website is with a website builder. Using a website builder doesn't require any programming and coding skills.

Can you migrate my existing website over?

Yes, and without issue. Regardless of how many websites you’re managing, we’ll bring all of them under the Verpex wing free of charge. Just send us the details of your websites when you’ve signed up to get started.

What are the customization options with a website builder?

Although website builders usually have some customization settings, like templates, fonts, margins editing, and so on, when compared to CMSs, it lacks customization options.

Discount

💰 90% OFF YOUR FIRST MONTH WITH ALL VERPEX RESELLER HOSTING PLANS

with the discount code

MOVEME

Use Code Now
Jivo Live Chat