OSX 上的 Firefox 计算错误 CSS

Firefox on OSX miscalculates CSS calc

我们创建了一个定制的网格系统,该系统使用 calc() 来确定列宽在扣除装订线的固定值后......基本上 CSS 输出如下:

.column{
  width: calc((((100% - 35px ) / 8) * 1) + 0px);
}

...对于 8 列网格的单列宽度。

在此实例中(在此断点处)100% 宽度等于 916px.

.column{
  width: calc((((916px - 35px ) / 8) * 1) + 0px);
}

如果您算一下,列宽现在应该是 110.125px;但是,Firefox 计算宽度为 110.133px(根据 Firebug)或 111px(根据 Firefox Web 检查器)。当您再次乘以它并添加排水沟时,您会得到 916.064px 的值(或 923px,具体取决于您信任哪个值)比父级宽 - 最后一列低于其余列。

只需将装订线调整为 4px 即可轻松修复,但我很想知道 OSX 和 calc() 的 Firefox 是否存在任何已知问题,或者是否存在calc() 本身有问题。

编辑:

同时我确定这个问题不仅出现在 5px 的装订线中,而且出现在所有不均匀的数字上。

旁注:

如果您想知道其中看似不必要的值,calc() 输出是通过 mixin 生成的,它允许我们仅指定网格中的列数、列跨度和固定间距宽度如下:

  $column-span: nth($column-settings, 1);
  $total-columns: nth($column-settings, 3);
  $total-gutters: ($total-columns - 1);
  $sibling-gutters: ($column-span - 1);
  width: calc((((100% - #{($gutter-setting * $total-gutters)} ) / #{$total-columns}) * #{$column-span}) + #{($gutter-setting * $sibling-gutters)});

所以这证明是 Firefox 本身的数学运算 bug/issue - Mozilla 开发人员之一的解释:

The reason the math doesn't work the way you expect is that it assumes that Gecko represents CSS lengths with infinite (or at least very high) precision. This is not the case. Pixel sizes are represented internally as integers with a factor of 60, so 916px becomes 54960, and 35px is 2100. The first is divisible by 8, but the second is not (262.5), leading to a rounding error (262). So, the calc() expression is represented internally as "0.125*W - 262", so with W=54960 we get: 6870 - 262 = 6608 (which in CSS pixels corresponds to: 6608 / 60 = 110.1333333333).

建议的解决方法(由另一个拥有类似数学问题的网格系统的用户提出)是添加一个 hack,至少在 Firefox 本身修复问题之前:

@media screen and (min--moz-device-pixel-ratio: 0) {
  .column:last-child{
    margin-right: -2px;
  }
}

... 这会抵消因不正确的舍入而增加的额外宽度。这不是很适合未来,但它会完成工作;至少在修复浏览器错误之前。