94

There seems to be an issue with my page here: http://www.lonewulf.eu

When hovering over the thumbnails the image moves a bit on the right, and it only happens on Chrome.

My css:

.img{
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
    filter:alpha(opacity=50);
    -moz-opacity: 0.5; 
    opacity: 0.5;
    -khtml-opacity: 0.5;
    display:block;
    border:1px solid #121212;
}
.img:hover{
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
    filter:alpha(opacity=100);
    -moz-opacity: 1; 
    opacity: 1;
    -khtml-opacity: 1;  
    display:block;
}
zefs
  • 1,562
  • 4
  • 26
  • 44
  • Doesn't move for me on `22.0.1229.94 m` – Danny Oct 19 '12 at 18:21
  • 3
    It's best practice to put the hover on the A tag, not the image itself. – Diodeus - James MacFarlane Oct 19 '12 at 18:22
  • Yes .img is a href class. Should I give it a different name? maybe now it conflicts with ? EDIT: Nvm, I changed the name from .img to .thumb and still having this issue. Any other suggestion? – zefs Oct 19 '12 at 18:41
  • It's probably something Fancybox is doing. – Diodeus - James MacFarlane Oct 19 '12 at 18:56
  • I don't see the thumbnails moving on hover - Chrome v.22. No, a class called `img` will not conflict with `img` elements: one is selected with `img {..}` the other with `.img {...}`. Your website made me laugh ;) – tuff Oct 19 '12 at 18:58
  • Weird, using latest Chrome and they are moving on mine. It made you laugh, is that good or bad? First website I've uploaded on the web. – zefs Oct 19 '12 at 21:16
  • 4
    using a translation on the Z axis was the only solution that worked for me: http://stackoverflow.com/questions/12502234/how-to-prevent-webkit-text-rendering-change-during-css-transition/12820319#12820319 – Larry Sep 04 '13 at 13:07

14 Answers14

231

Another solution would be to use

-webkit-backface-visibility: hidden;

on the hover element that has the opacity. Backface-visibility relates to transform, so @Beskow's has got something to do with it. Since it is a webkit specific problem you only need to specify the backface-visibility for webkit. There are other vendor prefixes.

See http://css-tricks.com/almanac/properties/b/backface-visibility/ for more info.

Community
  • 1
  • 1
alpipego
  • 3,178
  • 2
  • 14
  • 26
  • This is the correct answer, but you have to say that the `backface-visibility` property has to be set on the `img` element. In my case, the element that has the opacity was the `a` element wich wrap the `img`, so your answer was not perfect for me. Btw, I also found this glitch on Firefox for Mac, so I suggest using every vendor prefixes. – Oliboy50 Jan 21 '14 at 14:55
  • 1
    @Oliboy50 Sorry, I have to argue that. Im my case, the faulty elements were mere empty `div`s with `background-image`. @alpipego Thanks for the solution! – bonflash Mar 24 '14 at 03:30
  • 1
    This worked for me but made my images look bad, pixellated instead of smooth. – Kieran Hunter May 27 '15 at 07:36
  • 1
    I don't know why it works, but I happened upon this and gave it a shot. This fixed a bug that kept coming up on my site for months now that I could never figure out. Thank you! – Shnibble Apr 14 '17 at 15:53
  • I also had to add a `z-index` to get the hover effect to work correctly for me. – Jack Aug 11 '17 at 13:45
34

For some reason Chrome interprets the position of elements without an opacity of 1 in a different way. If you apply the CSS attribute position:relative to your a.img elements there will be no more left/right movement as their opacity varies.

Dmitry Pashkevich
  • 12,206
  • 9
  • 49
  • 68
Rick Giner
  • 441
  • 4
  • 2
21

I had the same problem, I fixed it with css transform rotate. Like this:

-webkit-transform: rotate(0);
-moz-transform: rotate(0);
transform: rotate(0);

It works fine in major browsers.

DigCamara
  • 5,352
  • 4
  • 33
  • 45
Beskow
  • 211
  • 2
  • 2
15

Another solution that fixed this issue for me was to add the rule:

will-change: opacity;

In my particular case this avoided a similar pixel-jumping issue that translateZ(0) introduced in Internet Explorer, despite fixing things in Chrome.

Most of the other solutions suggested here that involve transforms (eg. translateZ(0), rotate(0), translate3d(0px,0px,0px), etc) work by handing painting of the element over to the GPU, allowing more efficient rendering. will-change provides a hint to the browser that has presumably a similar effect (allowing the browser to render the transition more efficiently), but feels less hacky (since it's explicitly addressing the problem rather than just nudging the browser to use the GPU).

Having said that, it's worth bearing in mind that browser support is not as good for will-change (though if the issue is with Chrome only then this might be a good thing!), and in some situations it can introduce problems of its own, but still, it's another possible solution to this issue.

Nick F
  • 8,686
  • 5
  • 66
  • 84
  • This should be the accepted answer. Only this worked for me in Firefox 84.0.1 under GNU/Linux, unlike the other answers. That this bug is left unsolved after all this time is mind-boggling. – Vilinkameni Jan 04 '21 at 20:50
10

I was need apply both backface-visibility and transform rules to prevent this glitch. Like this:

a     {-webkit-transform: rotate(0);}
a img {-webkit-backface-visibility: hidden;}
Jamland
  • 891
  • 13
  • 17
10

I had a similar issue with (non-opacity) filters on hover. Fixed by adding a rule to the base class with:

filter: brightness(1.01);
Juan Casares
  • 338
  • 3
  • 7
  • Same issue with a filter transition on hover. This fixed it for me too. – Josh Harrison Jan 30 '17 at 17:51
  • Using filter: brightness(1); on the img element fixed it for me, thank you – Sai Sep 07 '17 at 14:58
  • this worked for me, had a 1px issue when applying grayscale filter on an image on hover. Why can't browser devs fix all those things finally? Why do I have to use backface-visibility and all that stuff.... – Varin Sep 20 '17 at 14:09
  • This fixes it, but the transition animation stops working – Amin Dec 20 '17 at 22:49
6

backface-visibility (or -webkit-backface-visibility) only fixed the issue in Chrome for me. To fix in both Firefox and Chrome I used the following combination of above answers.

//fixes image jiggle issue, please do not remove
img {
  -webkit-backface-visibility: hidden; //Webkit fix
  transform: translate3d(0px,0px,0px); //Firefox fix
}
andersra
  • 1,053
  • 2
  • 12
  • 30
4

I encountered a similar issue in Safari 8.0.2, where images would jitter as their opacity transitioned. None of the fixes posted here worked, however the following did:

-webkit-transform: translateZ(0);

All credit to this answer via this subsequent answer

Community
  • 1
  • 1
James Fletcher
  • 1,208
  • 11
  • 12
2

I ran into this issue with images in a grid each image was nested in an that had display: inline-block declared. The solution that Jamland posted above worked to correct the issue when the display: inline-block; was declare on the parent element.

I had another grid where the images were in an unordered list and I was able to just declared display: block; and a width on the parent list item and declared backface-visibility: hidden; on the image element and there doesn't seem to be any position shift on hover.

li { width: 33.33333333%; display: block; }
li img { backface-visibility: hidden; }
2

The solution alpipego was served me in this problem. Use -webkit-backface-visibility: hidden; With this the image no move in hover opacity transition

/* fix error hover image opacity*/
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
Lenin Zapata
  • 1,232
  • 9
  • 13
2

I had trouble with all the other solutions here, as they require changes to the CSS that may break other things -- position:relative requires me to completely rethink how I'm positioning my elements, transform:rotate(0) can interfere with existing transforms and gives wonky little transition effects when I have a transition-duration set, and backface-visibility won't work if I ever actually need a backface (and requires a whole lot of prefixing.)

The laziest solution I found is to just set an opacity on my element which is very close to, but not quite, 1. This is only a problem if opacity's 1, so it's not going to break or interfere with any of my other styles:

opacity:0.99999999;
Josh from Qaribou
  • 6,006
  • 2
  • 20
  • 21
1

Having marked Rick Giner's answer as correct I then found out it did not fix the issue.

In my case I have responsive width images contained within a max-width div. Once the site width crosses that max width the images move on hover (using css transform).

The fix in my case was to simply amend the max width to a multiple of three, three columns in this case, and it fixed it perfectly.

sidonaldson
  • 20,187
  • 10
  • 47
  • 54
  • 1
    Thanks for the comment, I also noticed relative position not always works as solution so if this issue appears again I will try your method too. – zefs Feb 14 '13 at 14:07
0

I noticed you had opacity included in your CSS. I had the same exact issue with Chrome (the image moving on hover) .. all I did was disable the opacity and it was solved, no more images moving.

.yourclass:hover {
  /* opacity: 0.6; */
}
cssninja
  • 21
  • 3
0

Had the same issue, My fix was putting the class before the src in the img tab.