Trivia about why it's smooth.
Many tutorials suggest doing position: absolute and then changing top/left to move the thing around. That's suboptimal as it likely triggers layout.
I worked with native UI toolkits (Android especially) a lot. In those, layout and drawing are always separated. Re-layout is an expensive operation that you absolutely don't want to run every frame. Transforms though are free because the GPU does these calculations anyway.
So I use transform: translate() instead.
And, yeah, one thing that drives me mad about the web is that there's no distinct layout phase. You can't requestLayout() like you could on Android. You can't change things around and wait for the next layout pass — every single of your changes gets reflected immediately. Every dang time you change something that might affect layout, the layout gets recalculated, and only then does control return to your JS. You added 100 divs in a loop? It does it for every. single. one.