title: Scrolling Progress Bar
body: <p>What I'm trying to do is implement a progress bar to indicate how close one is to the end of the page in <strong>vanilla JavaScript.</strong> However, I'm running into a few issues.</p>
  
  <p>First of all, although the <code>body</code> element is being scrolled, <code>document.body.scrollTop</code> always returns <code>0</code>. I've sorted this out by using <code>document.scrollingElement.scrollTop</code>.</p>
  
  <p>It's been a while since I last implemented a feature like this, so I took to Stack Overflow and found <a href="https://stackoverflow.com/questions/10787782/full-height-of-a-html-element-div-including-border-padding-and-margin">this thread</a>, which jogged my memory a bit. From what I remember about the last time I implemented this feature, the formula should be something like the following, which was mentioned in that thread.</p>
  
  <pre><code>const progressBar = document.getElementById('footer__progress_bar')
  const totalValue = document.body.scrollHeight - window.innerHeight
  
  document.body.onscroll = () =&gt; {
    let currentValue = document.scrollingElement.scrollTop
    let offset = (currentValue / totalValue) * 100 - 100 + '%'
    progressBar.style.left = offset
  }
  </code></pre>
  
  <p>Unfortunately something is off with the script above and I can't seem to figure out what it is. For some reason the value of <code>offset</code> overshoots (and sometimes undershoots) the mark. I've created a <strong><a href="https://codepen.io/tOkyO1/pen/qYKLBe?editors=1111" rel="nofollow noreferrer">CODEPEN</a></strong> and the overshoot problem is persisting, so it seems as if the issue is the formula itself. Nonetheless, when I look at the numbers (window.innerHeight, body.scrollTop, et cetera), none of them seem to add up. Below are the numbers.</p>
  
  <pre><code>window.innerHeight ..................... 779
  document.body.clientHeight ............ 3210
  document.body.offsetHeight ............ 3212
  document.body.scrollTop .................. 0
  document.scrollingElement.scrollTop ... 2646
  </code></pre>
  
  <p>I've also noticed some super strange behaviour. <code>document.body.clientHeight</code> and <code>document.body.offsetHeight</code> will randomly change values when I refresh the page, so that they're almost constantly jumping back and forth from <code>X to Y</code>.</p>
  
  <p>Notably, the body element itself has a <code>height</code> of <code>auto</code> and no vertical margins, albeit some of its children do have vertical margins. The <code>main</code> element, which is where I'm embedding everything from the database, also has <code>height: auto</code>, yet it also returns <code>0</code> when I check its <code>scrollTop</code>.</p>
  
  <p><strong>Does anybody have any idea where I'm going wrong or why the numbers aren't adding up?</strong></p>