The difference between offsetTop, scrollTop & clientTop (& why you should never use them)

The cursor position is accessed by clientX and clientY from the event argument, this is not dependent on scroll

At the top left corner, it is 0,0 and on the bottom right corner it is max, max

The position of the element can be accessed in terms of the scroll by offsetTop and offsetLeft, offset signifies that it respects padding and border width

clientTop and clientLeft don’t respect border-width but they do respect padding

Evidently offsetTop and offsetLeft are read-only property

scrollTop is the vertical scroll distance inside that element, scrollLeft is the same for horizontal scroll

pageXOffset is the horizontal scroll distance

pageYOffset is the vertical scroll distance

offsetTop is read-only, while scrollTop is read/write.

clientWidth = width + padding

clientHeight = height + padding

offsetWidth = width + padding + border

offsetHeight = height + padding + border

Let’s implement a drag system with the gained knowledge

As event.clientX and event.ClientY values are not dependent on scroll and element.offsetTop and offsetLeft are dependent on the scroll. It is required to convert the cursor position to scroll dependent variable or offset position to scroll independently.

Let’s try the latter

percentage positioning

The Alternative

offsetTop has a bug, making it’s value suddenly become 0, same with offset left

element.getBoundingClientRect provides a better alternative because it’s free from bugs (duh!) & it is scroll independent so less code

percentage positioning

One more Problem

The element being dragged will snap to the cursor position, it will look rough

We must keep the offset of the position cursor, but how?


Not yet, there is still one more problem. If element is scaled or any other transform is applied, the abrupt snap will come hunting


use change in the cursor position, it will also decrease code as we on longer to calculate offset between cursor and element

But the position of an element would not adapt if the container size changes. so we need to change px to %


  • We need to convert percentage value to pixels
  • Add dy and dx to the new position we got from above
  • after adding dy and dx to corresponding values convert them to percentage with respect to the element’s parent height and width

Whole & Final Code

More resources

Written by

Finding Magic.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store