Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Google Chrome change background opacity?

I use the following CSS rule to set background color of div:

div {
    background-color: rgba(96, 96, 96, .1);
}

In Google Chrome v.42 in 'Computed' tab of Developer Tools I see this result rgba(96, 96, 96, 0.0980392);. I think, it looks like some web-kit optimization...

In FireFox v.36 computed background color equals to rgba(96, 96, 96, 0.1)

I've made a simple http://jsfiddle.net/sergfry/c7Lzf5v2/ that shows it in action.

So, can I prevent opacity changing in Google Chrome?

Thanks!

like image 465
Sergey Avatar asked Apr 15 '15 12:04

Sergey


People also ask

What is background opacity?

Opacity is the degree to which content behind an element is hidden, and is the opposite of transparency.

How do I make my chrome background white again?

Step 1: Launch Chrome and go to the Themes page on the Chrome store. Step 2: You will find various themes listed there, starting with Chrome's bunch of themes. Click on the theme that you want to apply. Step 3: Click on Add to Chrome for the theme that you want to use.


1 Answers

As stated by Quentin, this is an IEEE floating point issue.

0.1 doesn't actually exist in decimal floating point technically simply due to the way that binary works.

0.1 is one-tenth, or 1/10. To show it in binary, divide binary 1 by binary 1010, using binary long division:

enter image description here

As you can see, 0.1 in binary is 0.0001100110011....0011 and it will keep repeating 0011 on the end to infinity.

Browsers will pick and choose the closest available point to 0.1 and use that as the opacity instead. Some will go over and some will go under.

FireFox i would guess it just showing the human readable version but in reality, its really using a computer usable floating point.

As an example:

body {
    color: rgba(0,0,0,0.1); // actually 0.0980392
    opacity: 0.1; // actually 0.100000001490116
}

Two completely different values for exactly the same floating point.

This floating point issue can actually be replicated elsewhere within browsers using other languages such as Javascript. Javascript numbers are always 64 bit floating point (which i believe CSS is as well). This is more commonly known as Double-precision floating point. PHP also uses double-precision floating points.

64 bit floating point numbers are as you could guess, stored in 64 bits, where the number (the fraction) is stored in bits 0 to 51, the exponent in bits 52 to 62, and the sign in bit 63.

This causes problems down the line as it means integers are only counted as accurate up to 15 decimal points and can really only calculate up to 17 decimal points.

This means that numbers can round up very easily or may just not be stored correctly.

var x = 999999999999999;  // x = 999999999999999
var y = 9999999999999999; // y = 10000000000000000

The arithmetic for floating points can also be out of alignment by quite a lot in places as well. As I've shown above; 0.1 in decimal isn't actual 0.1 but 0.000110011... and so on. This means some basic maths can be completely wrong.

var x = 0.2 + 0.1; // x = 0.30000000000000004

You end up having to confuse the system to get the number you actually want. This can be done by * the number by 10 and then dividing it to get your actual wanted result.

var x = (0.2 * 10 + 0.1 * 10) / 10; // x = 0.3

Precision within computers floating point is very difficult and is even more difficult when there are multiple different implementations (or browsers) trying to do their best for speed and displaying the information they're given correctly.

There are quite a few different pieces of information regarding floating points and what the CSS processor (or JS as I expect may calculations will be the same) may be trying to achieve.

  • Exploring Binary - Why 0.1 does not exist
  • Javascript Numbers
  • Wikipedia - IEEE floating point
  • Wikipedia - Double-precision floating point
like image 104
Stewartside Avatar answered Nov 03 '22 00:11

Stewartside