返回

transform 与字体模糊——技术解析

前端

缘起

在开发 FreeNG 的 scroll 组件时,我遇到了一个奇怪的问题:当 transform 为 translate(0, -20.222px)(为小数)时,字体会变得模糊。当时的解决方案是将参数值改为整数,问题就解决了。

趁着有时间,我搞了一个例子,本来以为很容易重现问题,可是直接设置 transform: translate(0, -20.222px) 并不能重现。于是,我又设置了盒子旋转,这时问题出现了,字体确实变得模糊了。代码如下:

<div class="box" style="transform: translate(0, -20.222px) rotate(1deg);">
  模糊的文字
</div>

成因分析

为了弄清楚原因,我查阅了相关资料,并做了进一步的测试。我发现,当以下条件同时满足时,字体就会变得模糊:

  • transform 属性包含小数。
  • 元素使用了硬件加速。
  • 元素在屏幕上处于非整数像素的位置。

硬件加速

硬件加速是一种利用显卡来处理图形渲染的技术,可以显著提高渲染速度。但是,硬件加速也会带来一些问题,其中之一就是字体模糊。

非整数像素

当元素在屏幕上处于非整数像素的位置时,浏览器会使用一种称为“子像素渲染”的技术来显示元素。子像素渲染会将元素的每个像素拆分成多个子像素,然后在每个子像素上显示不同的颜色。这可以使元素看起来更加平滑,但也会导致字体模糊。

小数与模糊

当 transform 属性包含小数时,元素就会在屏幕上处于非整数像素的位置。此时,如果浏览器使用了硬件加速,就会导致字体模糊。

解决方案

要解决字体模糊问题,可以有以下几种方法:

  • 将 transform 属性值改为整数。
  • 禁用硬件加速。
  • 使用离屏渲染。
  • 使用抗锯齿。

将 transform 属性值改为整数

这是最简单的方法,但也是最容易出现问题的。如果 transform 属性值包含小数,元素就会在屏幕上处于非整数像素的位置。此时,如果浏览器使用了硬件加速,就会导致字体模糊。

禁用硬件加速

禁用硬件加速可以解决字体模糊问题,但会降低渲染速度。要在 Chrome 浏览器中禁用硬件加速,可以打开“chrome://settings/system”页面,然后将“使用硬件加速提升浏览体验”选项关闭。

使用离屏渲染

离屏渲染是一种在显存中创建图像的技术,可以避免字体模糊问题。要在 Chrome 浏览器中使用离屏渲染,可以使用 transform: translate3d(0, 0, 0) 属性。

使用抗锯齿

抗锯齿是一种消除锯齿的技术,可以使字体看起来更加平滑。要在 Chrome 浏览器中使用抗锯齿,可以使用 -webkit-font-smoothing: antialiased 属性。

总结

以上就是 transform 与字体模糊问题的原因和解决方案。在实际开发中,我们可以根据具体情况选择合适的方法来解决问题。