Cichy
Cichy

Reputation: 5292

Image shifting/jumping after CSS transition effect with scale transform in Firefox

I have a problem in latest Firefox browser version 34 (system: Windows 7, screen width: 1600px). I made effect with zooming images (in some container) after hover on it. I am using transform: scale(1.1) with transition: transform 0.3s ease-in-out. But when I hover on image, and after image zoom in.. it make some strange 1px-shifting. Some rendering browser bug, but I hope that existing some fix for it.

Most important CSS definition and part of HTML code:

figure {
   display: block;
   overflow: hidden;
   position: relative;
   backface-visibility: hidden;
}
figure img {
   width: 100%;
   transform: scale(1);
   transition: transform 0.3s ease-in-out;
   }
figure:hover img {
   transform: scale(1.1);
}
 <figure>
     <img class="img-responsive" src="http://lorempixel.com/600/400/fashion/7">
 </figure>

Sample with bug is online here: http://templates.silversite.pl/test/jumpingimg/

I saw also that somebody can fix it, but I do not know how, e.g. box "Our recent work" on http://demo.qodeinteractive.com/bridge/

Upvotes: 17

Views: 19621

Answers (6)

Sarp K
Sarp K

Reputation: 1

For people for whom the other fixes didn't work, how i ended up fixing this was adding a small scale value to the image even when it's not being hovered.

I think keeping the image in an active scale makes it so that the pixel rounding issue never happens because the image doesn't go from dynamic -> static.

.myimage {
  transform: scale(1.005);
}

.myimage:hover {
  transform: scale(1.2);
}

Upvotes: 0

grzehu
grzehu

Reputation: 156

7,5 years later it's still an issue and the now solution is will-change css property. Only IE won't get this, but others seems to be doing fine - no more px jumping (edit: on non retina screens).

figure {
   display: block;
   overflow: hidden;
   position: relative;
   backface-visibility: hidden;
}
figure img {
   width: 100%;
   transform: scale(1);
   transition: transform 0.3s ease-in-out;
}
figure:hover img {
   transform: scale(1.1);
   will-change: transform;
}

Upvotes: 4

Danny Lines
Danny Lines

Reputation: 33

I have just run into this same problem now. The solutions here didn't fix the issue, so I'm posting what I did to get this to work.

Like OP I had a container with oveflow hidden and was the same size as the image inside it. The image would scale on hover to create a 'zoom' effect - but when initially starting and ending the transition, the image was "jumping"/growing a tiny bit on the bottom and right-hand side. This made it jumpy and not smooth.

I had calculated the dimensions of my components based off of percentages, which caused them to be non-integers (Chrome). I have a feeling Scale & Scale3d round the pixel values when scaling, which caused this jump. I gave a parent container display:table, which caused all children to have their width/heights be rounded to be an integer value. This fixed the issue for me, and the images now scale smoothly!

Upvotes: 1

wittich
wittich

Reputation: 2321

I just run over the same issue and for me it looks like that the browser corrects the decimal pixel after the scaling is done. Or some how the height and the width doesn't get scaled equals and that gets corrected in the end.

So I think the solution is to use an image with a 1 x 1 ration factor.

So for me the code of the question works fine when I use a the lorempixel with a width and height of 400px.

Let me know if that solves the issue?!

figure {
   display: block;
   overflow: hidden;
   position: relative;
   backface-visibility: hidden;
}
figure img {
   width: 100%;
   transform: scale(1);
   transition: transform 0.3s ease-in-out;
   }
figure:hover img {
   transform: scale(1.1);
}
 <figure>
     <img class="img-responsive" src="http://lorempixel.com/400/400/fashion/7">
 </figure>

Upvotes: 0

Kosmonaft
Kosmonaft

Reputation: 1343

I had a similar problem on my project. All images were position: absolute; and the transform look like that:

figure img{
   transform: translate( -50%, 50%) scale(1);
   position: absolute;
   top: 50%;
   left: 50%;
}

figure img:hover{
   transform: translate( -50%, 50%) scale(1.1);
}

I replace every scale with scale3d and that solved my problem. The final styles look like that:

figure img{
   transform: translate( -50%, 50%) scale3d(1, 1, 1);
   position: absolute;
   top: 50%;
   left: 50%;
}

figure img:hover{
   transform: translate( -50%, 50%) scale3d(1.1, 1.1, 1);
}

Hope that's will fix your problem

Upvotes: 23

Rob Scott
Rob Scott

Reputation: 8049

On the link that you provided, http://demo.qodeinteractive.com/bridge/ , if you actually go here: http://demo.qodeinteractive.com/bridge/portfolio/gallery-style-condensed/two-columns-grid/ , you can see that, once looking at dev tools, that they apply a margin of "1px" on left/right side

.projects_holder.hover_text.no_space article .image img {
   margin: 0 1px;
}

If you disable that style, you'll see the image move as you're describing when hovering on the image.

Therefore, your CSS for the image should be:

figure img {
   width: 100%;
   transform: scale(1);
   transition: transform 0.3s ease-in-out;
   display: block;  /* (or inline-block) */
   margin: 0 1px;
}

Upvotes: 5

Related Questions