Back to Dictionary
Onboarding & Tours
●○○Ready to Use
Recommended defaultTooltip Fade & Nudge
A tiny popover label that slides exactly 4-8px outwards from its anchor element while fading in. Used to label icon-only buttons.
Use
Icon-only action buttons (e.g., Share, Delete, Edit)
Avoid
Critical form instructions (put them inline instead)
Safer Alternative
No safer default listed.
Risk Level
Low risk
Live Demo
What It Is
A tiny popover label that slides exactly 4-8px outwards from its anchor element while fading in. Used to label icon-only buttons.
✓When to Use
- Icon-only action buttons (e.g., Share, Delete, Edit)
- Glossary definition hovers
- Charts where hovering over a bar reveals exact metrics
✕When NOT to Use
- Critical form instructions (put them inline instead)
- Mobile apps (tooltips don't work well on touch)
Configuration Tips
- 01Initial state should be tucked slightly against the anchor (e.g., y: 4px for a top tooltip)
- 02Use an instant/very fast duration (100-150ms) to ensure it appears before the user moves away
You've Seen It In
Radix UILinearNotion
AI Implementation Prompts
Move from a fast scaffold to production details, then tune timing and edge states.
Add a tooltip to this icon that drops down slightly and fades in when I hover over the icon.
Reference Implementation
The same implementation approach used by the live preview, kept compact enough to inspect and adapt.
'use client';
import { motion, AnimatePresence } from 'framer-motion';
import { useState, useEffect } from 'react';
import { Info } from 'lucide-react';
export function TooltipFadeNudgeDemo({ isPlaying = false }: { isPlaying?: boolean }) {
const [isHovered, setIsHovered] = useState(false);
useEffect(() => {
if (!isPlaying) {
setIsHovered(false);
return;
}
const interval = setInterval(() => {
setIsHovered((prev) => !prev);
}, 1500);
return () => clearInterval(interval);
}, [isPlaying]);
return (
<div className="flex h-64 w-full items-center justify-center rounded-2xl bg-stone-50 p-6 shadow-sm ring-1 ring-stone-200">
<div className="relative flex items-center justify-center">
{"text-stone-400 italic">/* Anchor element */}
<button
className={`flex h-10 w-10 items-center justify-center rounded-full transition-colors ${isHovered ? 'bg-stone-200' : 'bg-white shadow-sm ring-1 ring-stone-200'
}`}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<Info className="h-5 w-5 text-stone-500" />
</button>
{"text-stone-400 italic">/* Tooltip Nudging Upwards */}
<AnimatePresence>
{isHovered && (
<motion.div
initial={{ opacity: 0, y: -4, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: -2, scale: 0.95 }}
transition={{ duration: 0.15, ease: 'easeOut' }}
className="absolute -top-10 flex items-center justify-center rounded bg-stone-900 px-3 py-1.5 text-xs font-medium text-white shadow-md z-10"
>
Info
{"text-stone-400 italic">/* Tooltip Arrow pointing down */}
<div className="absolute -bottom-1 left-1/2 h-2 w-2 -translate-x-1/2 rotate-45 bg-stone-900" />
</motion.div>
)}
</AnimatePresence>
</div>
</div>
);
}