sticky-js
sticky-js copied to clipboard
Wrong fixed width in Chrome and Edge
Hi, I just started using sticky-js and noticed a trouble on both Chrome and Edge. When my list of inline-blocks, containing text and with a floating point width (e.g. 873.45px) is read in getRectangle, it's floored (873px), pushing my last block on a new line. Looks like that element.offsetWidth element.clientWidth, element.scrollWidth are floored.
I encountered a similar issue where the rounded width of the sticky element varied by 1 pixel depending on the screen width, which caused it to wrap and misalign on certain screen sizes.
I did some research and the getRectangle() method in sticky-js uses clientWidth, which apparently always return integers instead of the more precise subpixel decimal values.
There is a browser function getBoundingClientRect() that returns more precise values. So when I swapped clientWidth for that in the getRectangle() method, the jumping issue was fixed.
To replicate this fix, in the getRectangle() method change this line:
const width = Math.max(element.offsetWidth, element.clientWidth, element.scrollWidth);
into these two:
const clientRect = element.getBoundingClientRect();
const width = Math.max(element.offsetWidth, clientRect.width, element.scrollWidth);
Maybe this helps someone else. I'm not sure why the library doesn't use getBoundingClientRect() in the first place, maybe I'm overlooking something here.
Well, maybe it's doe tu the complete reflow of document on any call to getBoundingClientRect
(and the obvious related performance degradation), though I figure out the original programmer didn't know about it :)
Another enhancement could be using IntersectionObserver
rather that scroll event ;)