# Shoot for the Moon

This article, part of the writing collection, was published on .

Don't be half-minded when dealing with fractions and pixels. How can we ensure all browsers interpret fractions in our CSS equally?

As CSS changes and morphs over time, we must not forget that legacy browsers remain unchanged; one gotcha that a legacy browser might snipe you with, if left unattended, is decimals.

A confusing subject for the uninitiated (myself included), decimals in CSS behave in a way that might not be straightforward to some, especially when you consider the variety of browsers and their individual behaviours.

## A Bit of Prerequisite Information Permalink ¶

It’s probably worth refreshing yourself on the various rounding methods used in CSS in various browsers. Alex Kilgour wrote an excellent article on the subject, Browser Rounding and Fractional Pixels, that’s more than worth reading through and bookmarking, if only for his concise table of rounding methods used by browsers and when they’re used. I’ve summarised these different rounding methods below, but I still recommend checking out Alex’s article.

truncate to x decimals
Strips all but the first x characters after the decimal.
Let x = 2
`12.3456%``12.34%`
round to x decimals
Rounds the figure to x decimals.
Let x = 2
`12.3456%``12.35%`
nearest integer
Same as round to x decimals but rounds to the nearest integer (whole number).
`12.3456%``12%`
`12.5000%``13%`
down
Same as nearest integer but always rounds down to the nearest integer.
`12.3456%``12%`
`12.9999%``12%`
sub-pixel rendering
This is the most complicated of the different methods of dealing with decimals in CSS. I will freely admit I know very little about what’s going on with sub-pixel rendering, but have drawn up a quick demo to show a little bit about how it works.

Sorry, this code snippet failed to load, but you can still check it out over on CodePen!

While the `width` of each box in the above demo is technically `133.3333px`, sub-pixel rendering comes into play, and its behaviour might be surprising. You might expect that the `width` of each box would be rounded individually, creating three `133px`-wide boxes, leaving one extra pixel of the full `400px`-wide `.parent` unaccounted for.

However, what is happening, as far as I can tell, is that the browser creates a tally of the leftover `0.3333px` from each of the three boxes and adds that one extra pixel of `width` to one of the three boxes. The exact mechanics of how this happens are a bit of a mystery to me (why does the middle box receive the extra pixel?), but the outcome makes some rhyme and reason.

But let’s not concern ourselves with the mechanics of sub-pixel rendering for now, and focus on legacy browsers that employ the less accurate methods of CSS rounding, such as down or nearest integer.

## An Example Permalink ¶

Let’s look at an example where we’re setting a percentage-based value that includes decimals. Please ignore the glaringly obvious magic number in this example!

``````.parent {
width: 1337px;
}
.child {
width: 60.029%;
}``````
• `.parent` `width` is set to `1337px`
• `.child` `width` is set to `60.029%`, as our target `width` is `803px`
• `1337px ÷ 100 &times; 60.029 = 802.58773px`

Modern browsers will utilise sub-pixel rendering to render a pixel value containing decimals; however, older browsers, like IE8, will truncate the percentage-based value to only two decimal places! This spells trouble in our particular case:

`1337px ÷ 100 &times; 60.02 = 802.4674px`

Even the above value is rounded to the wrong target value by a modern browser.

Due to discrepancies between browsers, we can’t be sure whether a value will receive sub-pixel rendering, be truncated, be rounded to the nearest integer, or even be rounded down (floored) to the nearest integer!

As a result, more often than not, I recommend overshooting your target value with your fraction, whether it be a percentage, em, or rem fraction. The reason for overshooting is such that any browser’s method of rounding decimals will achieve your target value.

## Brass Tacks Permalink ¶

So let’s use the running example, and modify it to match these conditions and ensure that, no matter the rounding method used by the browser, the end-result pixel value is consistent.

``````.parent {
width: 1337px;
}
.child {
width: 60.06%;
}``````
• `.parent` `width` is set to `1337px`
• `.child` `width` is set to `60.06%`
• `1337px ÷ 100 &times; 60.06 = 803.0022px`

Because the worst truncation that will occur is to `2` decimal places, our value of `60.06%` will satisfy each rounding method, and our target value of `803px` will be achieved cross-browser.

It’s also worth noting that a percentage-based value of `60.059%`, ever-so-slightly less than `60.06%`, will result in a computed value of `802.9888px`. This satisfies almost every method of rounding, but it still fails when rounding down. By making sure our computed value overshoots the target value, that is to say that the decimal value is slightly greater than the integer value, we satisfy the conditions to round down to our target value.

## The Takeaway Permalink ¶

When creating fractions resulting in decimals in CSS, make sure that your computed value overshoots your target value if you have to support legacy browsers.