Preview Card

A card of extra context that opens when you rest on a link

Primitive

A preview card shows what a link points to, like a profile, an article, or a definition, when the pointer rests on the link or it gets focus. Use it to help someone decide whether to follow the link. For a short label on an icon button, use Tooltip. For anything with controls inside, use Popover.

Preview

The type scale was drawn up by @maren over a long winter, then tested at every size it would ever be read.

Installation

Usage

Composition

PreviewCardContent renders the portal, positioner, popup, and viewport. The media, title, and description parts are optional; put any markup you like inside the content.

PreviewCardTrigger renders an <a>. Give it an href so the link still works for anyone who clicks, taps, or never sees the card.

Examples

Use PreviewCardMedia to run an image edge to edge along the top, in the 1.91:1 ratio of a page's og:image.

Before you pick a grid, read the notes on page rhythm.

Shared Card

Pass one handle from createPreviewCardHandle to a PreviewCard and any number of triggers, and the card glides between them, rendering each trigger's payload.

The triggers can sit anywhere in the tree, and a long list mounts one card instead of one per row.

Arrow

Set arrow to point the card at its trigger.

Wrapping Text

When the link wraps across lines, the card anchors to the line under the pointer, with no extra props.

The framework was first announced at a small developer conference and grew out of work on a long-running internal rendering engine that the team had maintained for years before open-sourcing it.

Accessibility

Keep essential information out of the card

Touch screens have no hover, so tapping the trigger follows the link and the card never opens. Anything a reader needs belongs on the page itself.

Keyboard and motion

Focusing the trigger opens the card after the same delay as hover, without animation, and Escape closes it. With reduced motion on, the card fades in and out and switching triggers crossfades the content, with no scale, blur, glide, or nudge.

API Reference

The PreviewCard component is built on top of Base UI's PreviewCard. All Base UI props are supported. The documentation below only covers custom props and modified defaults specific to our implementation.

For the complete Base UI API, see the Base UI PreviewCard documentation.

Utilities

createPreviewCardHandle

Creates a handle that connects one PreviewCard to triggers anywhere in the tree. Pass a type argument to type each trigger's payload. The handle also has open(triggerId), close(), and isOpen for driving the card from your own code.

Props

PreviewCardTrigger

Link that opens the card. Wraps Base UI's PreviewCard.Trigger.

PreviewCardContent

The card itself. Composes PreviewCard.Portal, PreviewCard.Positioner, PreviewCard.Popup, and PreviewCard.Viewport, and optionally PreviewCard.Arrow. Props are forwarded to PreviewCard.Popup.

Upgrading

If you're reinstalling over an earlier version, check these changes:

BeforeNow
Opened and closed instantly (delay={0}, closeDelay={0})400ms open and 200ms close delays. Pass delay={0} and closeDelay={0} on the trigger to keep the old timing.
arrow defaulted to truearrow defaults to false. Pass arrow to keep it.
Padding on the card, removed with className="p-0"Padding on the inner viewport. Use viewportClassName="[--viewport-padding:0px]".
Fixed w-64 cardSizes to its content up to 20rem. Set a width with className="w-64", and max-w-* to go past 20rem.