Firefox on OSX miscalculates CSS calc

114 views Asked by At

We have created a bespoke grid system that uses calc() to determine column widths after deducting a fixed value for gutter ... essentially the CSS output is as follows:

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

... for an 8-column grid's single column width.

In this instance (at this breakpoint) the 100% width is equal to 916px.

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

If you do the math, the column width should now be 110.125px; however, Firefox calculates the width to be 110.133px (according to Firebug) or 111px (according to Firefox web inspector). When you multiply that up again and add the gutters, you get a value of 916.064px (or 923px, depending on which value you trust) which is wider than the parent - the last column drops below the rest of the columns.

It's easy enough to fix by simply adjusting the gutter to 4px, but I would be very interested to know if there are any known issues with Firefox for OSX and calc() or if there is something wrong with the calc() itself.

Edit:

I have meanwhile established that this problem occurs not only with a 5px gutter, but for all uneven numbers.

Side note:

In case you were wondering about the seemingly unnecessary values in there, the calc() output is generated via mixin that allows us to specify only the amount of columns in the grid, the column span and the fixed gutter width as follows:

  $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)});
1

There are 1 answers

0
Jayx On BEST ANSWER

So this turns out to be a math bug/issue with Firefox itself - the explanation form one of the Mozilla devs:

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).

A proposed work-around (by another user who has a grid system with similar math issues) would be to add a hack, at least until the issue is fixed in Firefox itself:

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

... this negates the additional width added by the incorrect rounding. It is not very future proof, but it will get the job done; at least until the browser bug is fixed.