Hover Card
Hover-revealed detail panel anchored to a trigger. Built for profiles and contextual previews where clicking would interrupt the flow — a Dialog is still the right tool for anything interactive.
Preview
Live preview
Usage
Examples
Profile preview
<HoverCard>
<HoverCardTrigger asChild>
<a href="/u/adak" className="font-medium hover:underline">
{user.name}
</a>
</HoverCardTrigger>
<HoverCardContent>
<div className="flex gap-4">
<Avatar size="lg">
<AvatarImage src={user.avatarUrl} alt="" />
<AvatarFallback>{initials(user.name)}</AvatarFallback>
</Avatar>
<div>
<p className="text-sm font-semibold">{user.handle}</p>
<p className="text-sm text-muted-foreground">{user.bio}</p>
</div>
</div>
</HoverCardContent>
</HoverCard>Placement and delay
<HoverCard openDelay={150} closeDelay={100}>
<HoverCardTrigger asChild>
<Button variant="outline">Hover me</Button>
</HoverCardTrigger>
<HoverCardContent side="top" align="start" sideOffset={8}>
<p className="text-sm">Shown above and left-aligned after 150ms.</p>
</HoverCardContent>
</HoverCard>Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| HoverCard open / onOpenChange | boolean / (open: boolean) => void | — | Controlled open state — hover opens it, blur and Escape close it. |
| HoverCard openDelay / closeDelay | number | 700 / 300 | Milliseconds before the card opens or closes after pointer movement. |
| HoverCardTrigger asChild | boolean | — | Uses your own element as the trigger (Radix Slot). |
| HoverCardContent side | "top" | "right" | "bottom" | "left" | "bottom" | Preferred side of the trigger; flips when there is no room. |
| HoverCardContent align | "start" | "center" | "end" | "center" | Alignment of the card against the trigger edge. |
| HoverCardContent sideOffset | number | 6 | Gap in pixels between trigger and card. |
| HoverCardContent className | string | — | Merged last — override width, padding or content. |
Accessibility
Accessibility notes
- The card opens on hover and on keyboard focus of the trigger, so it is reachable without a pointer.
- Escape closes the card and focus stays on the trigger.
- Use a real link or button as the trigger — the card supplements it, it never replaces the trigger's own name or role.
- Hover cards are not for content users must act on: keep anything essential visible without hovering, and use a Dialog for interactive content.
- The content is rendered in a portal with a heading-free layout — give it a readable structure (name, then description).
- Pointer users get a delay before it opens, avoiding flicker while the cursor crosses the page.