Tooltip Delay and Instant Subsequent Opens: Best Practices from the Skills Repository

Implement an initial 150ms delay on the first tooltip to prevent accidental activation, then remove both delay and entrance animation for subsequent tooltips to create a snappier, more responsive toolbar experience.

The emilkowalski/skills repository documents precise animation standards that separate amateur interfaces from polished professional UIs. Mastering the balance between tooltip delay and instant subsequent opens is one of the highest-impact micro-interactions for perceived performance. These patterns are codified in the Design Engineering and Animation Review skill files, providing concrete implementation strategies for React, vanilla JavaScript, and CSS-based tooltips.

Why Use an Initial Tooltip Delay?

An initial delay prevents accidental hover activation when users sweep their cursor across a toolbar. Without this pause, tooltips flash sporadically, creating visual noise that feels buggy rather than helpful.

As documented in skills/emil-design-eng/SKILL.md (lines 141-144), the ~150ms delay signals that the UI is "thinking" before providing extra information. This brief pause transforms the interaction from chaotic to deliberate, improving the overall perceived performance of the interface. The delay acts as a filter, ensuring tooltips only appear when users actually intend to read them.

Why Make Subsequent Tooltips Instant?

Once the first tooltip is visible, the user has accepted that tooltips provide useful context. At this point, any additional delay or entrance animation becomes redundant friction. Removing both the delay and animation for subsequent tooltips makes the entire toolbar feel significantly faster.

According to skills/review-animations/STANDARDS.md (line 49), skipping the delay and animation for follow-up tooltips is explicitly recommended as a performance optimization. This pattern maintains user flow by allowing rapid scanning of multiple controls without forcing the user to wait for each tooltip to animate in. The result is a cohesive experience where the first tooltip sets expectations, and subsequent appearances deliver information immediately.

CSS Implementation for Delay and Instant Modes

The architectural foundation relies on CSS custom properties and data attributes to toggle between delayed and instant states. In skills/emil-design-eng/SKILL.md (lines 52-66), the implementation uses data-instant to override transition properties.

Base Tooltip Styles

/* Standard tooltip with delay and animation */
.tooltip {
  transition: transform 125ms ease-out, opacity 125ms ease-out;
  transform-origin: var(--transform-origin);
}

/* Hidden state for entrance/exit animations */
.tooltip[data-starting-style],
.tooltip[data-ending-style] {
  opacity: 0;
  transform: scale(0.97);
}

/* Instant mode removes all transition delays */
.tooltip[data-instant] {
  transition-duration: 0ms;
}

The transform-origin: var(--transform-origin) declaration is critical. As noted in skills/emil-design-eng/SKILL.md (lines 51-58), tooltips must scale from the trigger element rather than the center to maintain spatial consistency and reinforce the physical connection between the trigger and the tooltip.

JavaScript State Management

To achieve instant subsequent opens, track the currently active tooltip in JavaScript and inject the data-instant attribute for any tooltip that follows an already-visible one.

let activeTooltip = null;

function showTooltip(tooltip) {
  // If a tooltip is already visible, make this one instant
  if (activeTooltip) {
    tooltip.dataset.instant = "";
  } else {
    tooltip.removeAttribute('data-instant');
  }

  // Trigger entrance animation (or instant appearance)
  tooltip.dataset.startingStyle = "";
  requestAnimationFrame(() => tooltip.removeAttribute('data-starting-style'));
  
  activeTooltip = tooltip;
}

function hideTooltip(tooltip) {
  tooltip.dataset.endingStyle = "";
  
  requestAnimationFrame(() => {
    tooltip.removeAttribute('data-ending-style');
    tooltip.removeAttribute('data-instant');
    if (activeTooltip === tooltip) activeTooltip = null;
  });
}

This state machine ensures that the first tooltip renders with the full 150ms delay and 125ms ease-out animation, while subsequent tooltips bypass both timing constraints entirely.

Animation Timing and Easing Standards

Per skills/review-animations/STANDARDS.md (lines 44-45), tooltip animations should complete within 125–200ms. The repository recommends a strong ease-out curve to make the motion feel responsive immediately upon trigger.

.tooltip {
  transition: transform 125ms cubic-bezier(0.23, 1, 0.32, 1), 
              opacity 125ms cubic-bezier(0.23, 1, 0.32, 1);
}

The cubic-bezier(0.23, 1, 0.32, 1) curve creates a snappy deceleration that feels natural for small popover elements. Additionally, the standards file (lines 48-49) mandates keeping all UI element animations under 300ms to avoid a sluggish interface feel.

Auditing Your Implementation

When reviewing tooltip implementations, reference the audit checklist in skills/improve-animations/AUDIT.md (line 46), which specifically flags: "tooltip delay + animation on every tooltip in a toolbar (after the first, they should be instant)."

Check for these common violations:

  • Missing instant mode – Ensure data-instant (or equivalent logic) is applied to subsequent tooltips after the first open.
  • Excessive duration – Clamp transitions to 125–200ms; anything longer feels unresponsive.
  • Center scaling – Replace transform-origin: center with var(--transform-origin) to scale from the trigger.
  • Zero initial delay – Maintain the ~150ms initial delay to prevent accidental activation during cursor sweeps.

Summary

  • Initial delay (~150ms) prevents accidental tooltip activation when users move cursors across toolbars.
  • Instant subsequent opens remove transition delays and animations after the first tooltip, dramatically improving perceived toolbar performance.
  • Animation duration should stay between 125–200ms with a strong ease-out curve (cubic-bezier(0.23, 1, 0.32, 1)).
  • Transform origin must reference the trigger element via var(--transform-origin), not the tooltip center.
  • State tracking in JavaScript enables the data-instant toggle that differentiates first opens from subsequent ones.

Frequently Asked Questions

How long should the initial tooltip delay be?

The emilkowalski/skills repository recommends approximately 150ms for the initial delay. This duration is long enough to filter out accidental cursor sweeps but short enough to feel immediate when a user intentionally hovers to read tooltip content.

Should I completely disable the entrance animation for subsequent tooltips?

Yes. According to skills/review-animations/STANDARDS.md (line 49), subsequent tooltips should skip both the delay and the entrance animation entirely. Setting transition-duration: 0ms via a data-instant attribute or equivalent class ensures instant appearance without motion.

What if my tooltips are positioned differently (top, bottom, left, right)?

The transform-origin property should dynamically reflect the tooltip's position relative to its trigger. Pass the specific origin (e.g., center bottom for top-positioned tooltips) via the --transform-origin CSS variable. This ensures the scale animation always emanates from the attachment point, regardless of orientation.

How do I handle multiple independent tooltip groups on the same page?

Scope the activeTooltip state to each logical group (such as individual toolbars or card collections). Instantiate separate state managers for each group, or add a data-tooltip-group attribute to your tracking logic so that tooltips in different groups don't trigger instant mode for each other, maintaining the delay pattern per isolated context.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →