The problem is that, when .slider listens for mousemove events, its child, .thumb, gets the events first. The event.offsetX value is measured relative to the target, which is either .slider or .thumb. Thus, if you click and slide on the middle of slider, .thumb jumps underneath the pointer, and suddenly distance is measured from the left edge of .thumb rather than .slider. That's why it kept skittering back and forth.
Two approaches to fix it: 1) use pointer-events: none to turn off pointer events for all children of .slider. There are still a number of issues that have to be considered. For example, if I mousedown on .slider but mouuseup off .slider, then it doesn't see the mouseup. That's why mouseup is attached to body. 2) Stop using offsetX and start upsing pageX-(left edge of .slider).
Another annoying thing is that, if you grab .thumb and slide off .slider, it ignores mousemove until you slide back on. So maybe mousemove should be hooked to body, but then you need to stop using offsetX.
Also note that I updated movethumb() to position the *middle* of the thumb to the indicated position. Note I could have called movethumb(event.offset - 12), but that breaks our abstraction, which is that movethumb() positions the *center* of .thumb at some offset in .slider. The computer doesn't work this way, but we write our code in layers to let us think about the problem the way we want, and then our layers map our thoughts into what the computer actually does.
Also note how I turned this simple challenge into a presentation. I expect you to do the same.