Use getBoundingClientRect to avoid manual offset/scroll calcs