前言

最近遇到一个这样的问题,在一些机型上的loading转圈动画看起来有点抖,转起来像个椭圆,心想会不会是这个icon宽高不同造成的,但看了一眼代码里面宽高写的是一样,按理来说这个loading应该是一个正圆,旋转起来不应该抖才是的。

比如这样:

亚像素渲染:浏览器如何处理小数像素的渲染?_浏览器

<div class="w-20px h-20px border-rd-50% loading"></div>
  • 1.

宽高相等的一个正圆,旋转起来看着怪怪的。事实上这是由于rem单位转换导致出现的小数像素(亚像素)问题

亚像素渲染:浏览器如何处理小数像素的渲染?_宽高_02

可以看到0.2rem计算过后的值为19.72px,这样就出现了亚像素,但是它宽高依然还是相等的,旋转起来也不应该出现抖动的现象🤔

这应该跟浏览器的渲染有关系,计算出来的像素为小数,那么对于小数像素浏览器是如何进行渲染的?

CSS值的处理过程

CSS值的定义到最终渲染实际上会经过一系列的步骤,这一过程在W3C Recommendation中有介绍,整个过程一共分为6步:

  • 声明值:应用于元素的每个属性都会为它提供一个声明值,当然也可能存在多个,比如在多个样式表中重复声明
  • 级联值:这一步其实就是在计算样式属性的权重,从而得到一个权重最高的值
  • 指定值:它一般等于级联值或者默认值,继承属性用的继承值 inherit,非继承属性将用初始值 initial,也可以显式的设置 initial/inherit/unset 等关键字,从而保证每个元素上的每个属性都存在一个值
  • 计算值:这一步是为CSS计算得出的值,转为需要使用的像素值(色彩值等等),注意这里最终得到的是绝对单位,比如rem在这一步就会转换成px
  • 使用值:获取计算值并完成所有剩余计算的结果,使其成为文档格式化中使用的绝对理论值。
  • 实际值:使用值原则上可以直接使用,但用户代理可能无法在给定环境中使用该值。例如,用户代理可能只能渲染具有整数像素宽度的边框,因此可能必须近似于已使用的宽度。此外,元素的字体大小可能需要根据字体的可用性或font-size-adjust属性的值进行调整。实际值是进行任何此类调整后的已使用值。