HoverCard
A rich floating card that appears on hover over a link or inline element. Built on the @base-ui/react/preview-card primitive. Use for user profiles, link previews, and rich contextual data where a Tooltip is too small.
Anatomy
HoverCardContent is a floating card with a default width of w-64. It accepts side, align, sideOffset, and alignOffset for positioning. Content is fully custom — compose whatever layout fits the preview.
@origin-ui
hover to openside="bottom" (default)w-64 default width
Examples
Positioning
side and align work the same as Popover.alignOffset (default: 4) provides horizontal inset from the trigger edge.
side="bottom"side="top"Design Guidelines
Do
- Use for supplemental rich previews. HoverCard shines for user @mentions, repository links, and inline entities where hover previews add genuine value.
- Keep content concise. A profile card, a link preview, a few stats — not a full page of information.
- Ensure the trigger is independently accessible. The card only shows on hover — the underlying link or element must work without it.
Don't
- Don't use as a Tooltip replacement. Tooltip is for short labels; HoverCard is for rich previews. Mixing the two confuses the interaction model.
- Don't put interactive content users must click. HoverCard dismisses on mouse leave — buttons and links inside may be unreachable before the card disappears.
- Don't rely on it for critical info. Content is invisible to keyboard-only and touch users — it is supplemental, never essential.
Developer Reference
Accessibility
- Built on
@base-ui/react/preview-card— usesrole="dialog"internally. - HoverCard content is not keyboard-reachable by default — the trigger element (link/button) must independently provide the same information or navigation.
- Hover delay is controlled by the Base UI primitive — no
TooltipProviderneeded. - Decorative images or avatars inside the card should use
aria-hidden.
Usage
import {
HoverCard,
HoverCardTrigger,
HoverCardContent,
} from "@/components/ui/hover-card"
import { CalendarDays } from "lucide-react"
// User profile preview
<HoverCard>
<HoverCardTrigger asChild>
<a href="/users/janedoe" className="underline underline-offset-4">
@janedoe
</a>
</HoverCardTrigger>
<HoverCardContent className="w-72">
<div className="flex gap-3">
<img src="/avatars/janedoe.png" alt="" aria-hidden className="size-10 rounded-full" />
<div className="space-y-1">
<p className="text-sm font-semibold">Jane Doe</p>
<p className="text-xs text-muted-foreground">Product designer</p>
<div className="flex items-center gap-1 text-xs text-muted-foreground">
<CalendarDays className="size-3" />
Joined March 2022
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>
// Positioning
<HoverCardContent side="top" align="start" sideOffset={8}>
...
</HoverCardContent>