Browser Rounding and Fractional Pixels
Whilst researching the building of a responsive, percentage width grid, I needed to find out how different browsers dealt with width values containing decimal places. I found lots of information on how some browsers round fractional pixels to the nearest integer, some round down, and newer browsers use sub-pixel rendering to visually represent fractions of a pixel.
I wanted to find out how different browsers dealt with percentage widths with decimal places e.g. 33.33333333%
, and also what they did when the value of that width contained a fraction e.g. 254.2483px
.
During the course of my research I found plenty of posts about how to handle various versions of Internet Explorer, or how to combat the effects of rounding, but I could not find a place that tried to document the behaviour of as many browsers as possible. With this in mind I have started a table below trying to document as many different browser behaviours as I can - I have tried to check key versions of browers, and identify the versions where sub-pixel rendering was introduced.
Percentages THEN Pixels
Interestingly I found that there are two actions taken by the browser: firstly on the percentage itself - for example - Internet Explorer 7-11 will truncate any percentage to 2 decimal places, more modern browsers will round to a large number of decimal places.
Then the second action is on the resultant pixel value calculated using that percentage.
Example
- We have a container with a width of
1325px
. - Inside that we have a box with a width set to
50.5290112%
in the CSS. - This should give us a pixel width for the box of
669.5093984px
by using the calculation(1325 / 100) x 50.5290112
. -
In Internet Explorer 8 the width of the box is actually
669px
. - What is happening in IE8 is that the browser is truncating the percentage to
50.52%
. - Which results in a pixel width of
669.39px
by using the calculation(1325 / 100) x 50.52
. - The browser then rounds this down to the nearest integer, resulting in an actual width of
669px
.
I have produced a test page to allow you to test the effect in different browsers.
One other oddity worth noting is that Internet Explorer 7 treats fractional pixels differently if they are the result of a percentage calculation (nearest integer), to if they are expressly defined in the CSS (rounds down). This can be seen in Example 3 of the test page.
The Spec
The HTML5 Specification doesn’t mention truncating or rounding decimal places. Point 11 deals with decimal places, and says to keep looping until “position is past the end of input, then return value as a length”.
Browser Table
This table details how different browsers treat percentage and pixel values with decimal places.
- The “percentages” column details any truncation of percentage values carried out by the browser
- The “round pixels from percentage” column details how browsers round fractional pixel values that result from percentage width calculations
- The “round pixels” column shows the rounding method used if fractional pixel values are expressly set in the css
Percentages | Round pixels from percentage | Round pixels | |
---|---|---|---|
Internet Explorer 7 | truncate to 2 decimal places | nearest integer | down |
Internet Explorer 8 | truncate to 2 decimal places | nearest integer | nearest integer |
Internet Explorer 9 | truncate to 2 decimal places | nearest integer | nearest integer |
Internet Explorer 10 | truncate to 2 decimal places | sub-pixel rendering | sub-pixel rendering |
Internet Explorer 11 | truncate to 2 decimal places | sub-pixel rendering | sub-pixel rendering |
Firefox 3.0 | truncate to 3 decimal places | nearest integer | nearest integer |
Firefox 3.5 | truncate to 3 decimal places | sub-pixel rendering | sub-pixel rendering |
Firefox 31 | truncate to 3 decimal places | sub-pixel rendering | sub-pixel rendering |
Chrome 20 | round to 15 decimal places | down | down |
Chrome 21 | round to 15 decimal places | sub-pixel rendering | sub-pixel rendering |
Chrome 37 | round to 13 decimal places | sub-pixel rendering | sub-pixel rendering |
Safari 6 (OSX Lion) | round to 15 decimal places | down | down |
Safari 6.1 (OSX Mountain Lion) | round to 15 decimal places | sub-pixel rendering | sub-pixel rendering |
Safari 7 (OSX Mavericks) | round to 15 decimal places | sub-pixel rendering | sub-pixel rendering |
Mobile Safari 7 (iOS7) | round to 15 decimal places | down | down |
Mobile Safari 8 (iOS8) | round to 15 decimal places | sub-pixel rendering | sub-pixel rendering |
Chrome 36 (Jelly Bean) [Nexus5] | round to 15 decimal places | sub-pixel rendering | sub-pixel rendering |
Chrome 30 (KitKat) [S5] | round to 15 decimal places | sub-pixel rendering | sub-pixel rendering |
Android Browser 4 (Jelly Bean) [Nexus7,Nexus4,S4,S3] | round to 15 decimal places | down | down |
Android Browser 4 (Ice Cream Sandwich) [Nexus,KindleFire2] | round to 15 decimal places | down | down |
Android Browser 4 (Gingerbread) [S2] | truncate to 3 decimal places | down | down |
Opera 12 | truncate to 2 decimal places | down | down |
Opera Next 24 | round to 13 decimal places | sub-pixel rendering | sub-pixel rendering |
Conclusions
Hopefully the information about how browsers treat fractional pixels and sub-pixel rendering will be useful to someone. If I’m totally off track here feel free to let me know, and send over some links and information so I can update this post with the most accurate information I can.
##Further reading
Find this post useful, or want to discuss some of the topics?