Gesso
Overlays

Hover card

A raised preview that opens when the pointer rests on a link, for a person or an issue.

Hover card shows a short preview of what a link points to, like a person's name and recent activity, when the pointer rests on it. It uses the same raised surface as Popover, and it is for extra detail only, because it does not open on touch and its content cannot be reached with the keyboard.

Usage

import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from '@/components/ui/hover-card';

<HoverCard>
  <HoverCardTrigger href="/people/maya">Maya Chen</HoverCardTrigger>
  <HoverCardContent>maya@ramson.tech</HoverCardContent>
</HoverCard>

HoverCardTrigger renders an <a>, so give it an href to make it a link that can take focus, or set asChild to put the behavior on your own link. In development, a trigger with neither logs a warning in the console. The content portals to the end of <body> and sets its own font-sans and text-fg. It is 256px wide on bg-surface-raised with rounded-lg, p-4, text-sm, shadow-md, and a 1px ring-border-strong, and className merges onto it, so set a width or a layout there.

Placement

The card opens below the trigger, centered on it, 4px away. It flips to the opposite side when there is no room. Set side, align, and sideOffset on HoverCardContent to change this, and the other placement props are Radix's.

Delays

The card opens after the pointer has rested on the trigger for 700ms, and closes 300ms after the pointer leaves the trigger and the card. Moving the pointer from the trigger onto the card within that time keeps it open. Set openDelay and closeDelay in milliseconds on HoverCard to change either one.

The card also stays open while a press began on it or text inside it is selected, so a reader can copy from it. open, defaultOpen, and onOpenChange control it from outside.

Accessibility

  • Keyboard focus on the trigger opens the card, after the same openDelay, and moving focus away closes it. A trigger with no href cannot take focus, so it has no keyboard path at all, and in development the kit warns about it in the console.
  • Escape closes the card.
  • Radix removes every tabbable element inside the card from the tab order, so a link or button in it cannot be reached with the keyboard. Put nothing in it that a reader must be able to operate.
  • It does not open on touch. Radix ignores touch pointers on both the trigger and the card, so a tap follows the link and shows no card.
  • The card has no role, and the trigger does not point at it with aria-describedby, so a screen reader is not told that it opened. Treat the content as an extra for sighted pointer users, and keep anything a reader needs on the page the link goes to.
  • Under reduced motion the card appears and disappears without its fade.
  • It has no forced-colors rule. The system replaces the fill, and a ring and shadow are removed there, so the card can lose its edge against the page.

When to use something else

  • Tooltip for one short line that names or explains a control. It opens on keyboard focus with no wait and is described to a screen reader, though it also does not open on touch.
  • Popover when the content must be reached by everyone, or holds a link, a button, or a field. It opens on press, works on touch and with the keyboard, and takes focus inside.
  • A visible label or line of text on the page, when the detail matters. A hover card should only repeat what the link already leads to.

Install

shadcn add @gesso/hover-card

On this page