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

User profile

@janedoe

Link preview

origin-ui/docs

Repository stats

origin-ui/components

Positioning

side and align work the same as Popover.alignOffset (default: 4) provides horizontal inset from the trigger edge.

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 — uses role="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 TooltipProvider needed.
  • 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>