Chrome在隐藏<div>后不会重绘。

26

我有一些用于鼠标悬停时显示并随后隐藏的 div。然而,在 Chrome(19.0.1084.56 m,Windows XP)中,当你取消悬停时,Chrome 并不会立即将它们消失,直到你做一些像滚动或调整窗口大小之类的操作。

http://jsfiddle.net/y7NdR/3/

我知道我的 CSS 的某些修改可以解决问题,例如删除 position, z-index, 和 overflow 属性,但我真的不想这样做 -- JSfiddle 是从我需要它们的完整站点精简而来的。

有人能否解释一下为什么在 Chrome 中会出现此重绘问题?有没有什么技巧可以修复它,而又不影响我需要的 CSS?


它并不是真正的菜单,但它是下拉式的。 - brentonstrine
看起来div可以作为列表项,使用类似于菜单的下拉标记和样式。例如http://www.htmldog.com/articles/suckerfish/dropdowns/。这在早期版本的IE中也无法正常工作,因为:hover选择器只能在锚点上工作。这似乎是jQuery可以使用show()或hide()在悬停时有所帮助的东西。不确定您是否想要走这条路。 - Christopher Marshall
我可以在最新的Chrome Canary版本中重现。 - thirtydot
谢天谢地,我只需要支持IE8及以下版本,技术上不需要支持Chrome,但我更希望网站在所有现代浏览器中都能正常工作。下拉菜单的内容不一定是列表,但如果是,我会像这样标记它[(http://jsfiddle.net/y7NdR/4/)。对于这个问题,jQuery似乎有点过重了,因为它目前只使用了4个CSS规则就可以在所有浏览器中工作,但如果无法解决重绘问题,我可能会考虑从头开始重新设计它。 - brentonstrine
另一个与Chrome相关的错误(同样的解决方法适用)......在折叠叠加元素后,屏幕上留下了水平伪影线。 - rgb
只是为了其他遇到这个问题的人,这个 bug 在 Mac 上的 Chrome 34 中仍然存在。似乎在其他浏览器中都可以正常工作(包括其他 WebKit 引擎,如 Safari)。Thirtydot 的修复确实解决了这个问题。 - Thomas
2个回答

39

很明显,这是一个 WebKit 的 bug 。

我发现添加 -webkit-transform: scale3d(1,1,1); 可以修复它:

http://jsfiddle.net/thirtydot/y7NdR/5/

我不确定这个修复方案是否有任何副作用。我猜这个方法可以工作是因为在 WebKit 内部,使用了不同的代码来渲染 3D 变换。


完美运作,正是我希望存在的技巧。谢谢! - brentonstrine
1
@brentonstrine - 你应该考虑提交一个 bug 报告(为了更好的结果)。 - Joseph Silber
@JosephSilber:我之前实际上发现了一个类似的 bug:https://bugs.webkit.org/show_bug.cgi?id=60047。不确定为什么我没有在这里发布它。脑子短路了。 - thirtydot
1
太棒了!在一整天的头痛之后,这个解决方法起了作用。谢谢你。 - Josh Stuart
2
有趣的是这个不起作用,而不是-webkit-transform: translate3d(0,0,0);。当Chrome成为新的IE时,需要使用hack才能正常工作,这个世界变得如此之糟 :( - Tokimon
对于我在OSX上,这个修复程序会影响页面上的滚动条。它会使它们出现在子组件下面。z-index也没有帮助。 - Nelu

3

我长时间以来一直在苦苦挣扎,尽管添加了 -webkit-transform: scale3d(1,1,1); 解决了我的问题,但我希望知道为什么会这样。所以,我深入挖掘了我的代码,试图缩小我的问题范围。我发现我正在使用一个淡入动画,并在其中包含了同一类别:

-webkit-backface-visibility:hidden;
backface-visibility:hidden;

仅仅删除这两行代码就解决了我的问题,而不需要使用规模变换的技巧。

由于背面可见性与变换有关,不应对2D变换产生影响,因此我将其删除并完全解决了我的问题。

在Chrome中,已经注意到了许多关于背面可见性的错误,因此我发布了这个内容,帮助未来的人们找到解决方案,而不需要太多工作。


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