Warm tooltips open instantly

Delay the first tooltip; neighbors then open instantly, unanimated.

Emil Kowalski@emilkowalski
Tooltips should have a delay before appearing to prevent accidental activation. Once a tooltip is open, hovering over other tooltips should open them with no delay and no animation. This feels faster without defeating the purpose of the initial delay.
Sep 1, 2025View on X ↗
Emil Kowalski@emilkowalski
Radix disables the delay by default as long as another tooltip opens within `300ms`.
Sep 1, 2025View on X ↗

From emil-design-eng; demo 1 rebuilds his B / I / U toolbar.

Sweep the toolbar

Rest on B, then slide across. Or press Sweep both.

Every tooltip waitsBad

    0ms waited

    delay 600ms · fade 125ms
    Skip after the firstGood

      0ms waited

      600ms, then 0ms within 300ms
      let openTip = null, lastClose = -Infinity, timer;
      
      function enter(tip) {
        clearTimeout(timer);
        const warm = openTip || performance.now() - lastClose < SKIP_MS;
        if (openTip) close(openTip);
        if (warm) show(tip, { instant: true });
        else timer = setTimeout(() => show(tip), DELAY_MS);
      }
      function leave(tip) {
        clearTimeout(timer);
        if (openTip === tip) { close(tip); lastClose = performance.now(); }
      }
      
      .tooltip { transition: transform 125ms ease-out, opacity 125ms ease-out; }
      .tooltip[data-state="closed"] { opacity: 0; transform: scale(0.97); }
      .tooltip[data-instant] { transition-duration: 0ms; }

      The skip window

      Open a tooltip, then cross the gap quickly.

      One shared providerSkip on

      Cold · 600ms

      skipDelayDuration: 300 · delayDuration: 600
      <Tooltip.Provider delayDuration={600} skipDelayDuration={300}>
        <Toolbar />
      </Tooltip.Provider>

      Why it matters, pros and cons

      Why it matters

      The delay filters a passing pointer. After one tooltip, intent is proven.

      Pros

      • Exploring a toolbar costs one delay.
      • Accidental hovers still show nothing.
      • Radix does it by default.

      Cons

      • Needs one shared provider across tooltips.
      • A long skip window makes tooltips flash back.
      • Touch has no hover; never hide required info.