浏览器是以 1 / 64 px 为单位而非整数 1px 来计算盒子尺寸与布局的,这使百分比、计算、小数点式的尺寸值成为可能,当然也会造成精度丢失。
这是因为 100px 宽的容器,内部有 6400 个 1 / 64px 的显示单位。66.5px 宽是占用 4256 个显示单位,33.5px 宽是 2144 个显示单位,4256 + 2144 = 6400,当然是可以塞进去的。虽然两个盒子最终会被渲染成 67px 与 33px 宽,但这并不是简单四舍五入的结果,而是图像引擎较为底层的处理。
如果像素宽度在乘以 64 倍后依然有小数点,那么不同浏览器会采用不同策略(向上或者向下取整)来判定实际的宽度,但一定会进行取整,因为这是最小的处理显示单位。
总之,渲染盒子尺寸的过程可以概括为:
在样式中设置尺寸(包括通过百分比、calc() 等计算后的)
将尺寸转换为 1 / 64px 的最小单位并取整——在这一步会有精度丢失
渲染实际尺寸——可以用 element.getBoundingClientRect() 来看到浏览器实际渲染时的尺寸。