WebKit: CSS缩放+translate3d导致文字模糊

61
我发现一个问题,当在Chrome和其他WebKit浏览器中应用css缩放并且同时使用translate3d时,会出现内容模糊的情况。
这里有一个JSFiddle示例:http://jsfiddle.net/5f6Wg/。(在Chrome中查看。)
.test {
  -webkit-transform: translate3d(0px, 100px, 0px);
}

.testInner
{
  /*-webkit-transform: scale(1.2);*/
  -webkit-transform: scale3d(1.2, 1.2, 1);
  text-align: center;
}
<div class="test">
  <div class="testInner">
    This is blurry in Chrome/WebKit when translate3d and scale or scale3d are applied.
  </div>
</div>

有没有已知的解决方法?我知道在上面的简单示例中,我可以简单地使用translate而不是translate3d—这里的重点是将代码简化到最基本。


我认为这个问题已经解决了,对我来说看起来不模糊。 - neaumusic
一个小的补充:在最新版本的Chrome中,我遇到了一个问题,就是当使用非圆整值进行translate3d时会出现模糊。将它们四舍五入后,所有的模糊问题都得到了解决。 - saroff
8个回答

36

为了提供硬件 3D 加速,WebKit 将 3D 变换元素视为纹理而不是向量。唯一的解决方案是增加文本的大小并缩小元素,实质上创建一个更高分辨率的纹理。

参见这里:http://jsfiddle.net/SfKKv/

请注意,抗锯齿仍然不够好(笔画丢失),因此我用一些文本阴影来增强文本。


1
移动端的 WebKit 会慢很多吗? - Alex K
很棒的解决方案,看起来有点像视网膜方案,但是针对桌面。喜欢这个想法,正在实施中,超级赞。 - ReSpawN
7
在 Chrome 版本 54.0.2840.71 m (64 位) 中,这看起来相当糟糕。 - Amethi

35

我发现使用:

-webkit-perspective: 1000;

在Android Nexus 4.2上尝试了一段时间后,我发现你的字体或图标集的容器让事情更加清晰。


3
太棒了,这就解决了问题!还有-webkit-transform: translate3d(0,0,0)。在缩放结束时,字形以一种奇怪的方式出现,而这个解决了它。试过了其他所有可能的方法。 - jwinn
1
假设这是因为这些属性会触发GPU加速,从而提高这些元素的过渡性能! :) - hallodom
1
@SergeiBasharov 我认为原帖并不需要移动解决方案。在桌面上它什么也做不了。我点赞了这个答案,但仅此而已。 - Teodor Sandu
我也需要 -webkit-transform: translate3d(0,0,0) - Phil Hudson

28

CSS滤镜效果是一种允许操作任何HTML元素外观的图形处理。自Chromium 19以来,这些过滤器已经进行了GPU加速,使它们变得非常快。

CSS3引入了一堆标准的滤镜效果,其中之一是模糊滤镜:

-webkit-filter: blur(radius);
‘半径’参数会影响屏幕上有多少个像素混合在一起,因此较大的值会创建更多的模糊效果。当然,将值设为零将不改变图像。
将半径设置为0将强制浏览器使用 GPU 计算并强制保持您的 HTML 元素不变。就像应用“硬边缘”效果一样。
因此,对我来说解决这个模糊的问题的最佳方案是添加这个简单的代码行:
-webkit-filter: blur(0);

还有一个已知的bug,它只影响视网膜屏幕。(请参见此处:为什么在Retina屏幕上Webkit / Chrome中的模糊(0)不能去除所有文本模糊?)。因此,为了使其也适用于视网膜屏幕,我建议添加第二行:

-webkit-transform: translateZ(0);

1
请将以下与编程有关的内容从英语翻译为中文。仅返回已翻译的文本:请在回答中提供一些解释。 - Blip
作为一条注记,动态在开发工具中应用模糊效果似乎与页面加载时有所不同。不确定是否只是我这样,但这可能是你要寻找的答案,只需重新加载页面即可。 - Spaceman
5
在尝试了谷歌搜索的所有其他方法之后,这个解决方案起了作用。谢谢! - th317erd
这对我有用!.modal { max-width: calc(100% - 50px); max-height: calc(100% - 50px); position: fixed; top: 50%; left: 50%; -ms-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); transform: translate(-50%, -50%); -webkit-filter: blur(0); overflow: hidden; } - Nateous
1
maoosi的答案以前对我有用,但是似乎有些变化,因为在最新版本的Chrome中不再起作用了? - Amethi

5

试试这个

 ...{
zoom:2;
-webkit-transform: scale(0.5);
transform: scale(0.5);
}

或者,您可以调用JavaScript函数来重新计算变换矩阵,通过删除矩阵的小数值来实现更精确的方法。请参见:https://dev59.com/X14c5IYBdhLWcg3w7t7E#42256897


对我来说,只使用 zoom: 1.005; 就可以了,不需要使用 scale - Jithin Raj P R
很遗憾,“zoom”无法进行动画处理,因此在帧中使用它会显得很生硬。@JithinRajPR - Aaron Meese

2

在使用isotope插件(http://isotope.metafizzy.co/index.html)和zoom插件(http://janne.aukia.com/zoomooz/)的组合时,我遇到了这个问题。我编写了一个jQuery插件来处理我的情况。如果有人可以从中受益,我将其上传到github存储库中。- https://github.com/charleshimmer/jquery-hirestext


0

我使用JavaScript将文本向上移动1像素,然后在100毫秒后向下移动1像素。这几乎是不可察觉的,并且完全解决了跨浏览器的问题。


-1
body {
-webkit-font-smoothing: subpixel-antialiased;
}

我认为你可以将其放在特定元素上,但我遇到了一个问题,一个元素影响整个网站。

我认为这是自定义字体的问题。


1
感谢您在这里尝试增加价值,但我提供的JS Fiddle没有使用自定义字体,而且-webkit-font-smoothing似乎没有任何区别。在上面的Fiddle中是否有效? - phil
1
在Chrome中,子像素抗锯齿字体平滑现在是默认设置。 - posit labs

-2
Webkit将3D变换元素视为纹理而不是矢量,以提供硬件3D加速。这与此无关。您会注意到,通过添加持续时间和方向信息(例如0.3线性),可以解决您的别名问题。您试图在运行时渲染所有内容。以上内容同样适用。

3
抱歉,汤姆,我不知道你在说什么。你是在谈论添加动画吗?(原意只是缩放,没有任何动画意图。)如果你修改原始的JS Fiddle,也许会有所帮助。 - phil
由于我正在使用转换,因此我添加了持续时间和方向。模糊仍然存在。 - Quentin Engles

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