Warm tooltips open instantly
Delay the first tooltip; neighbors then open instantly, unanimated.
Emil Kowalski@emilkowalskiTooltips 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.
Emil Kowalski@emilkowalskiRadix disables the delay by default as long as another tooltip opens within `300ms`.
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 125msSkip after the firstGood
0ms waited
600ms, then 0ms within 300mslet 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.