Internet Explorer strips decimals

I have the following problem with IE when making calculations with floating-point numbers.

For instance, I have a div, which width is 150px and length 150px. I am subtracting say 15.78775456545464 from its width.

div.style.width = (parseFloat(div.style.width) - 15.78775456545464) + "px";

All major browsers return 134.21224543454537 px, but IE returns 134.21. Internet Explorer removes all the decimals, but the first TWO.

I’m using IE 10.

Is there a way to return all decimals in IE?

Hi,

Instead of using div.style.width, try using offsetWidth (or clientWidth if you don’t want to include borders).

This works for me in IE7 - 10, both when the styles are declared separately or inline.

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>offsetWidth</title>
    <style>
      #myDiv{
        width: 150px;
        height: 150px;
        background: black;
        color: lime;
        text-align: center;
      }
      #myDiv p{
        padding-top: 65px;
        font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
      }
    </style>
  </head>

  <body>
    <div id="myDiv"><p>Hello!</p></div>

    <div id="myDiv2" style="width:150px; height: 150px; background: black; color: lime;	text-align: center;">
      <p style="padding-top: 65px; font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;">Hello again!</p>
    </div>

    <script>
      var myDiv = document.getElementById("myDiv"),
          myDiv2 = document.getElementById("myDiv2");

      console.log("Div 1 width: " + myDiv.offsetWidth);
      console.log("Div 1 width - 15.78775456545464: " + (myDiv.offsetWidth - 15.78775456545464));

      console.log("Div 2 width: " + myDiv2.offsetWidth);
      console.log("Div 2 width - 15.78775456545464: " + (myDiv2.offsetWidth - 15.78775456545464));
    </script>
  </body>
</html>

I can not see the point of what you are doing @User908 ; and the IE rounding is still more precision than you need in this case.

Thanks for your reply, Pullo.

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>offsetWidth</title>
    <style>
      #myDiv{
        width: 150px;
        height: 150px;
        background: black;
        color: lime;
        text-align: center;
      }
      #myDiv p{
        padding-top: 65px;
        font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
      }
    </style>
  </head>
  
  <body>
    <div id="myDiv"><p>Hello!</p></div>
    
    <div id="myDiv2" style="width:150px; height: 150px; background: black; color: lime;	text-align: center;">
      <p style="padding-top: 65px; font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;">Hello again!</p>
    </div>
    
    <script>
    var myDiv = document.getElementById("myDiv"),
        myDiv2 = document.getElementById("myDiv2");
    
    console.log("Div 1 width: " + myDiv.offsetWidth);
    console.log("Div 1 width - 15.78775456545464: " + (myDiv.offsetWidth - 15.78775456545464));
    
    console.log("Div 2 width: " + myDiv2.offsetWidth);
    console.log("Div 2 width - 15.78775456545464: " + (myDiv2.offsetWidth - 15.78775456545464));
	myDiv2.style.width = (myDiv2.offsetWidth - 15.78775456545464) + "px"
	console.log(myDiv2.style.width)
    </script>
  </body>
</html>

I’ve modified your code, so you can see, that your example doesn’t work when setting myDiv2.style.width.
IE returns all decimals when not used to set object’s style width/height/top/left etc.

@Rubble there is point of what I’m doing. I just need IE to stop the rounding. Is it possible?

offsetWidth is a read-only property, so I don’t think that you’re going to be able to do what you want (I would be happy to be proved wrong).

However, you are worrying about a value of “0.01 pixel”.

Could you share what you are trying to do with us, as I would be genuinely interested to find out when that makes a difference.

No, not in CSS anyway, and not for px values.

And herein lies your answer: find a strategy to round on 2 decimals (the common denominator) all over the place by yourself and forget about browser diffs when doing numbers from JS to CSS.

Or… if you need exact calculation to translate to sane pixel values, use relative values, e.g.:


<div id="myDiv2" style="width: 33.555624%; height: 150px; background: black; color: lime; text-align: center;">
[...]
myDiv2.style.width = (myDiv2.offsetWidth(%) - 2.651231231) + "%"

However, as it was mentioned above, this isn’t normally a problem, and significance for subpixel values of up to so many decimals usually indicates a wrong approach.

@Pullo, I’m working on a zoom script and currently developing variable zoom, which will allow users to zoom In even closer using mousewheel. Something like this http://www.elevateweb.co.uk/image-zoom/examples#mousewheel
Opera also returns from one to two decimals, but it makes correct roundings. IE returns almost the same numbers, but sometimes they may vary by 0.01px.
You can see from the example above that when using mousewheel the size of the frame on the image is decreased proportionately and the size of the image to the right is being increased simultaneously. In my script the image to the right let’s say is multiplied by 5, so if the initial size of the image was 200x200 pixels, it will become 1000x1000 pixels in order to be displayed correctly.
When the user uses mousewheel I’m adding, for example, 0.205 to the 5 which increases the size of the image to the right. And I also decrease the size of the frame on the image by say 7.88787 pixels, to ensure that the correct part of the increased image is displayed.
It’s quite difficult to explain, so I hope that the link above will help you to better understand what I’m trying to say and do.

When it comes to browsers, they’ll just do their own thing. That’s why you can’t trust their rounding and passed number values, you have to handle the rounding yourself.

Take the example bellow. After rounding, the calculated width displayed in “style” attribute is 135.212px, yet the browser displays a computed 135.217px. Use Firebug or any other inspector.


|>width: 135.217px;
  --this.style 135.212px

And the features you’re describing here, zoom-in, zoom-out, subpixel values belong to SVG and canvas, not image frames.


<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>offsetWidth</title>
    <style>
      #myDiv{
        width: 150.78775456545464px;
        height: 150px;
        background: black;
        color: lime;
        text-align: center;
      }
      #myDiv p{
        padding-top: 65px;
        font-family:"Lucida Sans Unicode", "Lucida Grande", sans-serif;
      }
    </style>
  </head>

  <body>
    <div id="myDiv"><p>Hello!</p></div>

    <div id="myDiv2" style="width:150.78775456545464px; height: 150px; background: black; color: lime;  text-align: center;">
      <p style="padding-top: 65px; font-family:'Lucida Sans Unicode', 'Lucida Grande', sans-serif;">Hello again!</p>
    </div>

    <script>
      var myDiv = document.getElementById("myDiv"),
          myDiv2 = document.getElementById("myDiv2");

      console.log("Div 1 width: " + myDiv.offsetWidth);
      console.log("Div 1 width - 15.78775456545464: " + (myDiv.offsetWidth - 15.78775456545464));

      console.log("Div 2 width: " + myDiv2.offsetWidth);
      console.log("Div 2 width - 15.78775456545464: " + (myDiv2.offsetWidth - 15.78775456545464));

      myDiv2.style.width = (myDiv2.offsetWidth - 15.78775456545464) + "px";
      console.log(myDiv2.style.width);
    </script>
  </body>
</html>


You’re right @myty. However, in my case those decimals make difference.
Anyway, I’ve found solution to my problem.

And the answer is what; so that others can learn from this post?

Thanks for the link and the explanation User908!

That’s good. What did you end up doing?

Edit:

Looks like @Rubble ; beat me to it :slight_smile:

I suspect he dropped the whole thing and he’s using a third party library.

Your suspicion is wrong @myty. I don’t use third party libraries and only code on javascript. By doing so I learn things which I would have never learned if I used other libraries/frameworks.
Besides, 3rd party libs don’t always provide the capacity one sometimes needs to create new animations/plugins etc.
There are also cases when say some plugin written on jQuery won’t work when jQuery’s library is updated. Thus relying on your own code written on javascript is more secure than using other libraries.

Regarding @Pullo’s, @Rubble’s question (and those who’re interested) on how I overcame my problem.
I decided to calculate my div’s width and height on every mousewheel event. For instance, If I allow user to scroll 11 times to and fro, the script now calculates what the width of the div will be when scrolled say 9 times forward. And every time I return the exact number I need for every browser.
So, if I’ve scrolled say 8 times the script checks, if it is the 8th mousewheel event it returns the number needed for that event.
I hope my explanation makes sense.

PS. Sorry for any mistakes in the text, as English isn’t my first language.

Thanks for reporting back.
Maybe it’ll help someone else in the future.

Your English is excellent. No need to apologise :slight_smile:

Thanks for your explanation @User908 ; it is interesting to find out how people overcome their problems.

I’m sorry. I wanted to say not “ON every mousewheel event” but “FOR every mousewheel event”!
And the script makes calculations before the user starts scrolling, so I have all the numbers beforehand for every mousewheel event.

No problem @Pullo and @Rubble. You’re welcome.

You were really hung up on getting exact numbers in IE. You said that in your case those decimals make difference. And you said you’ve found a solution to your problem.

It would help best for you to be clear in your explanation: did you find a way to coerce IE into submission to accept more than two decimals?

I know the answer, but others may be still looking for an answer in all the wrong places.

The reason I’m posting this is not to create animosity. I believe it’s better for one to follow path on best practices. Believe it or not, libraries often do follow path on best practices. You should not dismiss proven and tested code. Even if you are JavaScript educated.

I’m not saying they don’t and I’m not dismissing proven or tested code. And of course, best libraries do follow path on best practices, otherwise they won’t be among the best.

I said that those decimals did make difference and I wanted to find a way to make IE return those decimals, but as I’ve found out it’s not possible, at least for now.
I just wanted to find a way to finish my project. And I finally did it by “circumventing” this problem and solving it in another way.

I do understand that you were/are indicating my wrong approach on solving this problem. Maybe you are correct that my whole approach regarding variable zoom was “wrong”, but I managed to find a way to solve this problem - a thing I was aiming for.

But, anyway, thanks for your replies, they were helpful as well.