# HoverCard A preview of what a link points to, shown while the pointer rests on it. ```ehtml Example import { HoverCard, HoverCardTrigger } from "@elements/ui/hover-card"; @ada
Ada Lovelace

Wrote the first program.

``` ## Parts | Part | What it is | |---|---| | `HoverCard` | The root: owns open, renders the trigger slot and, while open, the floating card. | | `.hover-card-media` | A class for the usual layout: an avatar or image, then a column of text. | | `HoverCardTrigger` | Wraps a link anywhere on the page for the HoverCard with the same handle. Takes handle and payload. | ## Attributes ### HoverCard | Attribute | Type | Default | Description | |---|---|---|---| | `open` | `boolean` (two-way) | `false` | Whether the card is open. Bind it to control it; the card writes false back when it closes itself. | | `openDelay` | `number` | `700` | ms the pointer (or focus) rests on the trigger before the card opens. 0 opens at once. | | `closeDelay` | `number` | `300` | ms after the pointer leaves the trigger and card before it closes. | | `side` | `"top" \| "right" \| "bottom" \| "left" \| "inline-start" \| "inline-end"` | `"bottom"` | Preferred side of the trigger; it flips when there is no room. inline-start and inline-end follow the text direction (right and left under dir=rtl). | | `align` | `"start" \| "center" \| "end"` | `"center"` | Alignment along that side. | | `sideOffset` | `number \| ((d: OffsetData) => number)` | `4` | Gap from the trigger, in px. | | `alignOffset` | `number \| ((d: OffsetData) => number)` | `0` | Shift along the alignment axis, in px. | | `avoidCollisions` | `boolean` | `true` | Flip and shift to stay on screen. | | `collisionAvoidance` | `{ side?: "flip" \| "shift" \| "none"; align?: "flip" \| "shift" \| "none"; fallbackAxisSide?: "start" \| "end" \| "none" } \| null` | `null` | How it stays in view. side "none" keeps the side with no flip, "shift" keeps the side and slides it over the trigger into view; align "flip" tries the other alignment before sliding, "shift" only slides, "none" neither; fallbackAxisSide "start" tries the inline start side of the other axis first, "end" (the default) the end side, "none" never moves it to the other axis. avoidCollisions={false} turns all of it off. | | `positionMethod` | `"fixed" \| "absolute"` | `"fixed"` | "absolute" places the card in page coordinates instead of viewport ones. | | `collisionPadding` | `number` | `8` | Distance kept from the viewport edge, in px. | | `collisionBoundary` | `string \| Element \| Element[]` | `""` | A selector or elements whose edges flip and shift keep it inside, besides the viewport. | | `arrowPadding` | `number` | `6` | Distance the arrow keeps from the corners, in px. | | `sticky` | `"partial" \| "always"` | `"partial"` | "always" keeps it in the collision boundary after its anchor scrolls away. | | `hideWhenDetached` | `boolean` | `false` | Hide the card while the trigger is scrolled out of view. | | `anchor` | `string` | `""` | CSS selector of an element to position against instead of the trigger. | | `keepMounted` | `boolean` | `false` | Keep the closed card in the page, hidden, rather than removing it. | | `disableAnchorTracking` | `boolean` | `false` | Place it once when it opens; it stays put while the page scrolls, and is placed again on a window resize. | | `handle` | `string` | `""` | Names it for HoverCardTrigger parts elsewhere on the page. | | `triggerId` | `string` (two-way) | `""` | The id of the active trigger's element. Set it with open to open against that trigger. | | `payload` | `string` (two-way) | `""` | The payload of the HoverCardTrigger it is showing for, for the content to read. | | `backdrop` | `boolean` | `false` | Dim the page under the open card. The pointer passes through it. | | `arrow` | `boolean` | `false` | Draw an arrow pointing at the trigger. | | `size` | `"auto" \| "sm" \| "md" \| "lg"` | `"md"` | Card width. auto fits the content. | | `class` | `string` | `""` | Extra classes on the card. | | `onOpenChange` | `(open: boolean, details: OpenChangeDetails) => void` | `() => {}` | Called when the card opens or closes itself, before the change. details.reason says why (trigger-press, trigger-hover, escape-key, outside-press, close-press, focus-out); details.trigger is the trigger element that caused it (undefined when no trigger did); details.cancel() keeps the current state. Not called for changes the caller makes. | | `onOpenChangeComplete` | `(open: boolean) => void` | `() => {}` | Called after the enter or exit animation finishes. | | `onEscapeKeyDown` | `(e: KeyboardEvent) => void` | `() => {}` | Called on Escape; e.preventDefault() keeps it open. | | `onPointerDownOutside` | `(e: PointerEvent) => void` | `() => {}` | Called on a press outside; e.preventDefault() keeps it open. | ### HoverCardTrigger | Attribute | Type | Default | Description | |---|---|---|---| | `handle` | `string` | (required) | The handle it is a trigger for. | | `payload` | `string` | `""` | Data handed to payload while this trigger is active. | ## Slots | Slot | Content | |---|---| | `trigger` | The element the pointer rests on, usually a link. It keeps its own role and gets data-state. | | `default` | The card's content. | ## Keyboard | Keys | Action | |---|---| | `Tab` | Focusing the trigger opens the card after openDelay; Tab again moves into links in the card, and leaving both closes it. | | `Enter` | Follows the trigger link. | | `Escape` | Closes the card. | ## Data attributes | Attribute | Values | On | Description | |---|---|---|---| | `data-state` | `"open" \| "closed"` | trigger, .hover-card | closed during the exit animation. | | `data-side` | `"top" \| "right" \| "bottom" \| "left"` | .hover-card, .popover-arrow | The side it ended up on. | | `data-align` | `"start" \| "center" \| "end"` | .hover-card | | | `--transform-origin` | position | .hover-card | The anchor-facing edge; the enter animation scales from it. | | `--anchor-width, --anchor-height` | px | .hover-card | The trigger's size. | | `--available-width, --available-height` | px | .hover-card | Room to the viewport edge; a tall card scrolls inside it. | | `--popover-arrow-size` | length | .hover-card | Set on the card's class to size the arrow. | | `data-popup-open` | present | trigger | While open; the same moment as the trigger's open data-state. | | `data-open / data-closed` | present | .hover-card, .popover-arrow | The open state as two flags; data-closed during the exit animation. | | `data-align` | `"start" \| "center" \| "end"` | .popover-arrow | The alignment it ended up with. | | `data-uncentered` | present | .popover-arrow | When the arrow cannot point at the trigger's middle (held off a corner). | | `data-anchor-hidden` | present | .hover-card | With hideWhenDetached: while the trigger is scrolled out of view. | | `data-starting-style / data-ending-style` | present | .hover-card | On the first frame of the enter animation, and through the exit animation. | | `--positioner-width / --positioner-height` | px | .hover-card | The card positions itself, so these are its own size while open. | ## Accessibility - A hover card is for sighted pointer users: it adds no role and nothing a screen reader must hear. The trigger keeps its meaning as a link. - Keyboard focus on the trigger opens it too, and its links can be reached with Tab while it is open. - Opening never moves focus. Touch does not open it; a tap follows the link. ## See also - [Popover](popover): Rich content in a floating panel, opened by a trigger, that keeps the page usable. - [Tooltip](tooltip): A short label for a control, shown on hover and keyboard focus.