非常难以解决且奇怪的CSS3不透明度过渡问题(...可能是一个bug?)

39
我遇到了一个非常令人沮丧和奇怪的CSS问题,让我抓狂。
我正在使用Bones模板制作网站,一直很好用,但现在出了问题...
它使用流体网格系统,我最近尝试创建一个简单的画廊,并将其制作成网格(4张图片,每张图片都包装在四分之一的列中,并为第一/最后的图像添加了类)。
如果你悬停在这些图片上(特别是前三张),你会注意到它们因某种原因而变窄了一两个像素。这些图片被设置为max-width:100%,我有一种感觉这可能是罪魁祸首,因为如果你给这些图片一个"固定"宽度(例如.gallery-icon img {max-width:165px;}),它就可以解决问题。但由于流体网格系统,我不能走这条路,因为如果调整浏览器大小,图片的宽度仍然保持在165像素,即使我根据媒体设置了4个不同的宽度,在媒体大小之间,图片也无法正确对齐。
如果不是转换效果问题(如果我关闭转换,图片的透明度会下降,但没有动画),它就会按照我的意愿工作:(请帮帮我!这里有一个空的演示网站,只有骨架样板运行和页面上的画廊。如果你看到抖动问题,请告诉我。(我无法在jsfiddle上重新创建它,所以我在一个我闲置的旧域名上安装了它)。编辑:我刚注意到问题似乎发生在宽度和高度都大于div的图像上。图像1+3如此,并且它们有错误,而图像2、4似乎没问题?而图像2+4的高度比div小…但即使我将图像设置为最大高度,问题仍然存在。编辑2:添加了一个快速视频来展示问题(最新的Firefox和Chrome)http://www.youtube.com/watch?v=uL81hLfMvvw

演示在 Google Chrome v24.0.1312.57 上似乎运行良好。 - SeinopSys
请再次检查,使用不同电脑上的Chrome浏览器,我确信这不仅仅是我的电脑问题。将鼠标悬停在图像1和3上并反复操作,仔细观察图像的右边框。虽然微妙,但当您有大量图像在屏幕上进行转换(flexslider滑动幻灯片)时,它是明显的,并且看起来很糟糕:(我使用相同的版本24.0.1312.57 m) - user1202292
我在Chrome 24.0.1312.57上看到了它。 - McNab
我刚刚更新了它,但问题仍然存在,在火狐浏览器中也出现了这个问题。 - user1202292
谢谢您的展示,显然您出于某种原因没有看到这个错误。我已经快速录制了一个屏幕截图,并编辑了问题以包含链接,请查看一下。 - user1202292
显示剩余2条评论
5个回答

101

感谢 vals 指出了 GPU 方面... 这让我想起这个 CSS 小技巧,可以解决 Chrome 渲染问题:

-webkit-transform: translateZ(0);

我已经将此应用到包含有问题项 (i.icon-) 的容器 (div.post) 上,该项具有分数宽度,问题解决了!
来源: 我从这个答案中获得了该解决方案,用于修复在导航到页面锚点后不正确渲染(固定)元素的问题。

在这里也为我的动画不透明度工作。 - Somebody
谢谢 - 这解决了我关于带有不透明度过渡的Bootstrap轮播的问题:http://stackoverflow.com/questions/19499404/webkit-issue-with-css3-opacity-transition - rda3000
令人惊讶的是,即使将不透明度转换应用于重叠在有缺陷元素上的其他元素,这个错误仍然会发生。这个解决方案对我很有效,谢谢! - Tzach
非常好!这种修复方式让我想起了IE的bug :( - Asaf
这也修复了标签<a>overflow:hidden属性的一个错误。在Android 4.4.2上,链接的轻触高亮显示未被截断。 - raacer

15
我觉得这实际上是Chrome(我使用的是24.0.1312.57 m版本)的一个错误。
问题并不在于图像1和3,我在图像2上也看到了这个问题。
我认为当图像宽度为小数时(比如146.71像素),问题就会出现。在静态显示中,它会被四舍五入为146像素。在过渡中,它会被向上舍入(更正确!)至147像素。

这完全有道理,我有一种感觉就是这个问题。意识到这点非常令人沮丧但却正确!这将解释为什么将宽度设置为一个整数 (165px) 可以修复它。 - user1202292
同时我已经在Canary中进行了检查。问题也存在,但是当您禁用GPU加速时,问题会消失。因此,问题可能是GPU(用于动画)启动时呈现不同。 - vals

12

使用以下CSS提示将受影响的元素提升到新的合成层(它解决了与我完全相同的问题):

.<your-css-selector> {
will-change: <css style about to change. example: opacity>;}

这意味着将元素的绘制过程隔离到一个新的合成层中。在Chrome开发工具中检查图层时,您可以确保该元素已经被提升,从而解决了问题。该元素将出现在一个新的层中,并带有以下“合成原因:拥有活动的加速动画或转换。具有will-change合成提示。”

看起来通过这种方式将元素提升到一个新的层后,浏览器能够正确地渲染转换的最终状态。

Ivan。


1
这个功能在提问时并不存在。但自从Chrome 36和FF 36以来,它现在可以使用了(链接)。 - rustyx
1
这个答案是最好的 - 它不需要将-webkit-transform: translateZ(0)添加到父元素。 - ranquild

4
在这个链接上,您可以找到解决Mozilla bug的方法。
您需要添加1个CSS规则:
-moz-backface-visibility: hidden;

1

我建议使用jQuery来处理透明度,而不是使用CSS3属性,因为你是正确的,你的最大宽度正在不幸地干扰你的过渡效果。

$(".gallery-icon img").hover(function(){
    $(this).fadeTo(fast, 0.7);
}, function(){
    $(this).fadeTo(fast, 1.0);
});

使用jQuery可以解决许多过渡效果的小问题,并确保您的不透明度更改在跨浏览器上兼容(是的,我知道有很多过渡标签适用于浏览器,但并非所有浏览器都支持所有属性。) :) 希望这有所帮助!

谢谢Tammy,非常有帮助 :) 尽管我喜欢CSS,但我不得不选择jQuery。 - user1202292
没问题!我也更喜欢 CSS,但并非所有的 bug 都能被解决,不是吗?也许有一天! - Tammy Shipps
这种方法会影响在Chrome中进行动画时元素的大小。当元素出现时,它会从0到100%逐渐动态变化宽度和高度。 - SalmanShariati

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