title: HTMLElement.offsetTop doesn't work in subpixel precision
body: <p>I am writing a small program where I move <code>DOM</code>s at a specified speed.</p>
  
  <p>When I move it at the rate of <code>20px per second</code>, the <code>offset</code> that gets added to the <code>elem.style.top</code> is about <code>0.3px per frame</code>.</p>
  
  <p>The problem is, when this <code>offset</code> is smaller than <code>0.5px</code>, <code>elem</code> doesn't move!</p>
  
  <p>I constructed a simplified example that can demonstrate the issue in my program:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="false" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var requestFrameAnimationId;
  
  function myMove(offset) {
    var elem = document.getElementById("animate");   
    requestFrameAnimationId = animationLoop(frame);
    function frame() {
      console.log(elem.offsetTop);
      if (elem.offsetTop === 350) {
        cancelAnimationFrame(requestFrameAnimationId);
      } else {
        elem.style.top = elem.offsetTop + offset + 'px'; 
        elem.style.left = elem.offsetLeft + offset + 'px'; 
      }
    }
  }
  
  function animationLoop(render) {
      var running, lastFrame = +new Date(); // casting Date to Number
      function loop(now) {`enter code here`
        requestFrameAnimationId = requestAnimationFrame(loop);
        running = render(now - lastFrame);
        lastFrame = now;
      }
      loop(lastFrame);
  }</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>#container {
    width: 400px;
    height: 400px;
    position: relative;
    background: yellow;
  }
  #animate {
    width: 50px;
    height: 50px;
    position: absolute;
    background-color: red;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
    &lt;body&gt;
      &lt;p&gt;
        &lt;button onclick="myMove(0.3)"&gt;Move at 0.3px per frame&lt;/button&gt;
        &lt;button onclick="myMove(0.5)"&gt;Move at 0.5px per frame&lt;/button&gt;
      &lt;/p&gt;
  
      &lt;div id="container"&gt;
      &lt;div id="animate"&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/body&gt;
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Try clicking on <code>Move at 0.5px per frame</code>. The rectangle should be moving.
  Reset it by clicking on <code>Run code snippet</code>.</p>
  
  <p>Now try clicking on <code>Move at 0.3px per frame</code>.
  It should be moving the DOM more slowly, but you can see that the DOM is not moving.</p>
  
  <p>It's strange because when I initially kept track of the <code>top</code> position in a javascript variable <code>topPos</code>, and applied <code>${topPos + offset}</code> to <code>elem.style.top</code>, it worked at even slower speeds!</p>
  
  <p>So my guess is that <code>elem.offsetTop</code> rounds the decimal values, so 0.3 becomes 0, and 0.5 becomes 1.</p>
  
  <p>What can I do to make it so that the DOM moves precisely at the specified speed? I can't use any libraries for this one.</p>
  
  <hr>
  
  <p>EDIT: I looked more into the problem and I believe it's <code>offsetTop</code> that rounds the numbers to integers.</p>
  
  <p>However, I found out that CSS OM spec changed the type of <code>offsetTop</code> to <code>float</code>, and <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=360889" rel="nofollow noreferrer">the Chromium team was working on applying the change on the browser more than 4 years ago, and it seems that it should be fixed by now</a>.</p>
  
  <p>Why is it not working on my program, and how can I make it work?</p>
  
  <hr>
  
  <p>EDIT2: I found from <a href="https://www.w3.org/TR/cssom-view/#scrolloptionsvertical" rel="nofollow noreferrer">CSSOM working draft</a> that the type of <code>offsetTop</code> was integer.</p>
  
  <pre><code>readonly attribute long offsetTop;
  </code></pre>
  
  <p>I think they only changed the type of <code>scrollTop</code> and <code>scrollLeft</code> to a double precision number.</p>
  
  <pre><code>attribute unrestricted double scrollTop;
  attribute unrestricted double scrollLeft;
  </code></pre>