A zoom effect can be created with the transform and transition CSS properties. I have been using this on a project and was not entirely happy with the result. For the project I created a grid with articles that become larger if you move the mouse over the article. The article contains an image and text. During the zooming the article gets blurry. This is very noticeable with text. Also the effect is not always very smooth, especially if you have more than a couple of article elements.
Below is a code example for the zoom effect:
<style>
article {
transition: all 300ms;
}
article:hover {
transform: scale(1.08);
}
</style>
<article>
<div class="image"><img src="thumbnail.jpg" alt=""></div>
<div class="content"><a href="/link/to/article">Title</a></div>
</article>
By scaling image and text the browser has to do a lot of work, especially if it is also doing a transition. So I figured faking the zoom effect would perform better.
My idea was not to scale anything. This way the browser has to do less work. I added a border on top of the article with an :after
pseudo-element. On mouse over I can animate the border width, creating the illusion that the article becomes larger. This worked quite well, but wasn't entirely smooth. I suspect that this is happening because border
is part of the CSS box model.
Below is the CSS code of the zoom effect with the border
property:
<style>
article {
position: relative;
}
article:after {
border: 10px solid #fff;
bottom: 0;
content: "";
left: 0;
position: absolute;
right: 0;
top: 0;
transition: all 300ms;
}
article:hover:after {
border-width: 0;
}
</style>
So next, I tried box-shadow. This CSS property offers an inset
value, that puts a shadow inside an element. And by setting the blur radius to 0
, you create an hard edge like with border
. The spread radius can then be used to create a border. This turned out to animate nicely. For Internet Explorer and Edge browsers I had to use -1px
for the article:after
positions to always cover the edges.
Below is the CSS code of the zoom effect with the box-shadow
property:
<style>
article {
position: relative;
}
article:after {
bottom: -1px;
box-shadow: inset 0 0 0 10px #fff;
content: "";
left: -1px;
position: absolute;
right: -1px;
top: -1px;
transition: all 300ms;
}
article:hover:after {
box-shadow: inset 0 0 0 0 #fff;
}
</style>
[Update] Another option is clip-path, but it doesn't work in Internet Explorer or Edge.
<style>
article {
clip-path: inset(10px);
transition: all 300ms;
}
article:hover {
clip-path: inset(0);
}
</style>
You can try the 4 different solutions in my zoom effect demo.
To support older browsers, you might want to put the CSS code through the autoprefixer.
I am pretty pleased with the result. It reminds me, that achieving an effect does not need to be technically correct, to be convincing to the eye.