悬停时图像移动 - Chrome 不透明度问题

94

我的页面似乎有问题:

http://www.lonewulf.eu

当鼠标悬停在缩略图上时,图像会向右移动,这只会在Chrome浏览器上发生。

我的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;
}

在我的 22.0.1229.94 m 上无法移动。 - Danny
3
最佳实践是将Hover效果放在A标签上,而非图像本身。 - Diodeus - James MacFarlane
是的,.img是一个href类。我应该给它起一个不同的名字吗?也许现在它与<img src>冲突了?编辑:算了,我把名称从.img改为.thumb,但仍然遇到了这个问题。还有其他建议吗? - Tasos
这可能是Fancybox正在做的事情。 - Diodeus - James MacFarlane
4
在我的情况下,只有在Z轴上使用翻译才起作用:https://dev59.com/KWcs5IYBdhLWcg3w437H#12820319 - Larry
显示剩余2条评论
14个回答

232

这是正确的答案,但你必须说backface-visibility属性必须设置在img元素上。在我的情况下,具有不透明度的元素是a元素,它包裹了img,所以你的答案对我来说并不完美。顺便说一句,我在Mac上的Firefox浏览器中也发现了此问题,因此建议使用每个供应商的前缀。 - Oliboy50
1
抱歉,我必须提出异议。在我的情况下,故障元素只是具有“background-image”的空div。@alpipego 感谢解决方案! - bonflash
1
这对我有用,但使我的图像看起来很糟糕,像素化而不是平滑。 - Kieran Hunter
1
我不知道为什么它能起作用,但我偶然发现了这个方法并尝试了一下。这解决了一个在我的网站上出现了几个月的bug,而我一直无法找到解决方法。谢谢! - Shnibble
我还不得不添加一个 z-index,以使悬停效果对我起作用。 - Jack

34

由于某些原因,Chrome会以不透明度为1的元素位置不同的方式来解释它们。如果您将CSS属性position:relative应用于您的a.img元素,则它们在透明度变化时就不会有左/右移动了。


1
有人知道这是为什么吗?肯定不是 hasLayout 的问题吧? - sidonaldson
9
刚刚在Firefox中也遇到了同样的问题。 relative 没有解决它,但在元素上设置以下代码可以解决问题:transform: translate3d(0px,0px,0px); - ConorLuddy
我在Safari上遇到了同样的问题,transform: translate3d(0px,0px,0px);解决了它。 - zevnicsca

21

我遇到了同样的问题,我通过CSS transform rotate解决了它。 就像这样:

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

它在主要浏览器中运行良好。


1
谢谢您。这在Firefox中修复了! :D - Hans Wassink
我也是。背面技巧对我没用(img内部),但这个方法行得通!谢谢! - mikmikmik
这是唯一对我有用的答案(Chrome)。谢谢! - Kid Diamond
此解决方案修复了在弹性容器中更改颜色时,项目向右移动1像素的问题。谢谢! - Piotr Sobuś

16

对我有效的另一个解决方案是添加规则:

will-change: opacity;
在我的情况下,这避免了在Internet Explorer中引入类似于translateZ(0)导致的像素跳动问题,尽管在Chrome中修复了问题。
大多数其他建议使用变换(例如translateZ(0)rotate(0)translate3d(0px,0px,0px)等)的解决方案都通过将元素的绘制交给GPU来实现更有效的渲染。 will-change为浏览器提供了一个提示,它可能具有类似的效果(使浏览器更有效地渲染过渡),但感觉不像黑客(因为它明确地解决了问题,而不仅仅是推动浏览器使用GPU)。
话虽如此,值得注意的是,浏览器支持并不像will-change好(尽管如果只有Chrome才有问题,那么这可能是一件好事!),在某些情况下会引入自己的问题,但仍然是解决此问题的另一个可能的方法。

1
这应该是被接受的答案。在GNU/Linux下,只有这个方法对我在Firefox 84.0.1中有效,而其他答案都不行。这个问题在这么长时间后仍然没有解决,真是让人难以置信。 - Vilinkameni

10

我需要同时应用 backface-visibilitytransform 规则来防止这种故障。 像这样:

a     {-webkit-transform: rotate(0);}
a img {-webkit-backface-visibility: hidden;}

10

我在鼠标悬停时遇到了(非不透明)滤镜的类似问题。通过在基础类中添加规则进行修复:

filter: brightness(1.01);

鼠标悬停时,使用过滤器转换时出现相同的问题。这个解决方法也为我解决了问题。 - Josh Harrison
在 img 元素上使用 filter: brightness(1); 对我有所帮助,谢谢。 - Sai
这对我有用,当我在悬停时为图像应用灰度滤镜时出现了1像素的问题。为什么浏览器开发人员不能最终解决所有这些问题呢?为什么我必须使用backface-visibility和所有这些东西... - Varin
这样修复了,但是过渡动画停止工作了。 - Amin

6

backface-visibility(或-webkit-backface-visibility)仅在Chrome中解决了问题。为了在Firefox和Chrome中都修复该问题,我使用了上述答案的以下组合。

//fixes image jiggle issue, please do not remove
img {
  -webkit-backface-visibility: hidden; //Webkit fix
  transform: translate3d(0px,0px,0px); //Firefox fix
}

4

我在Safari 8.0.2中遇到了类似的问题,当图片的透明度过渡时会抖动。这里发布的任何修复方法都没有起作用,但是以下方法有效:

-webkit-transform: translateZ(0);

所有的功劳归功于这个答案,该答案经由这个后续答案


尝试了所有其他答案,这是第一个有效的! - user1837158

2
我在这里遇到了麻烦,因为其他解决方案需要更改CSS,可能会破坏其他东西 - position:relative要求我完全重新考虑如何定位我的元素,transform:rotate(0)可能会干扰现有的转换,并在设置了transition-duration时产生奇怪的小过渡效果,如果我真的需要一个背面,backface-visibility将无法工作(并需要大量前缀)。
最懒的解决方案是仅在我的元素上设置一个接近但不等于1的透明度。只有当透明度为1时才会出现问题,因此它不会破坏或干扰任何其他样式:
opacity:0.99999999;

2

我在一个网格中遇到了图片问题,每个图片都嵌套在一个声明了display: inline-block的元素中。Jamland上面发布的解决方案可以在父元素上声明display: inline-block;来纠正该问题。

我有另一个网格,其中的图片位于无序列表中,我只需要在父列表项上声明display: block;和width,并在图像元素上声明backface-visibility: hidden;,悬停时似乎没有任何位置偏移。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接