How do you prevent layout thrash when measuring and positioning a tooltip?

What’s up everyone? I’m wiring up a tooltip that needs to anchor to a button, and I’m trying to keep it from janking the page when it shows or when the window resizes. Right now it works, but I can see layout shifts and I’m pretty sure I’m doing read/write interleaving like a champ (in the worst way).

function positionTip(btn, tip) {
  tip.style.display = "block";
  const b = btn.getBoundingClientRect();
  tip.style.left = `${b.left}px`;
  tip.style.top = `${b.bottom + 8}px`;
  const t = tip.getBoundingClientRect();
  if (t.right > window.innerWidth) tip.style.left = `${window.innerWidth - t.width - 8}px`;
}
window.addEventListener("resize", () => positionTip(btn, tip));

How would you restructure this so reads are batched and layout stays stable, without making it overly complex or laggy on resize?

1 Like