Skip to content

HoverCard ​

A hover/focus-triggered preview card whose popup stays open on hover (no flicker). Rich content slot, 12-way placement, separate open/close delays, arrow (incl. corner-merge), dual-axis offset, collision tuning, append-to container, delay groups and controlled display.

Basic usage ​

Hover or focus the trigger to show the preview card.

Trigger on hover

Hover to view

Rich content slot ​

The slot="content" slot accepts any HTML preview (links / buttons / images…). The popup stays open on hover: moving the pointer from the trigger into the card keeps it open, so links and buttons inside stay interactive (the hover area = trigger + popup panel).

Rich preview (hoverable popup)

Hover to view user
O
Ouyang Xiaoyu
Frontend Engineer · Hangzhou
Into open source and Web Components — code and writing.
MessageProfile

Placement ​

12 directions: top / bottom / left / right × start / center / end.

12 directions

top-starttoptop-endbottom-startbottombottom-endleft-startleftleft-endright-startrightright-end

Show / hide delay ​

open-delay / close-delay are configured separately: appears about 800ms after hover, closes 300ms after leaving. delay is a legacy alias (applies to both when the individual ones are unset).

Separate delays (open-delay / close-delay)

Separate delaysdelay alias

Arrow ​

The arrow is shown by default; arrow="false" hides it; arrow-point-at-center keeps the arrow pointing at the trigger center.

Arrow (default / hidden / pointing at center)

Default arrowHidden arrowPoint at center

Corner-merged arrow ​

arrow-merge: for -start /-end placements the arrow fuses with the panel corner into a right-angle triangle.

Corner-merged arrow (arrow-merge)

bottom-startbottom-end

Dual-axis offset ​

offset main-axis distance (gap between popup and trigger), skidding cross-axis shift.

Dual-axis offset (offset / skidding)

offset=20skidding=24

Width ​

width as a number (px) or trigger / target (same width as the trigger).

Width (width)

width=320width=trigger

Append-to container ​

append-to: mounts the card into a portal inside the specified container (the DOM belongs to that container) while the card keeps position: fixed viewport coordinates with no translation — handy for escaping clipping contexts such as overflow: hidden.

append-to container

Hover to view

Collision tuning ​

collision-padding viewport clamping padding; fallback-placements custom fallback sequence; hide-when-detached hides the card when the anchor is scrolled out of view; auto-adjust-overflow="false" disables auto adjustment.

Collision tuning

Collision paddingFallbackHide detachedNo adjust

Scroll follow & stickiness ​

Scrolling inside a scroll container repositions the card by default (sticky=partial); once the anchor leaves the viewport it hides per hide-when-detached (or clamps to the viewport edge when not enabled). sticky="always" pins the card to the viewport edge once the anchor scrolls out (stays visible). sticky="off" explicitly disables scroll repositioning.

sticky three modes (inside a scroll container)

sticky=partialsticky=alwayssticky=off

Custom collision boundary ​

collision-boundary: flips and clamps against the specified element's rect instead of the viewport (first match in multi-ancestor scenes); the collisionBoundary property accepts an element directly.

collision-boundary (boundary container)

Hover to view

Disabled ​

disabled: hover/focus no longer opens the popup (the controlled open attribute still works).

Disabled (disabled)

Hover does nothing

Delay group ​

Triggers sharing the same group value share delays: moving the pointer between members skips the open-delay (opens immediately) and closes the previous one immediately.

Delay group (group)

User AUser BUser C

Controlled display & events ​

The open attribute controls visibility; visibility changes dispatch oas-open-change (detail: { open }). Hover/focus triggers still apply in addition.

Controlled display (open + oas-open-change)

ShowHideopen: falseTrigger element

Tap to toggle on touch ​

Hover is unreliable on touch devices (pointer: coarse): the hover card automatically degrades to tap to toggle — tap the trigger to open, tap again to close, or tap anywhere outside the card and the trigger to close. Desktop hover behavior is unchanged.

Tap to toggle (automatic on coarse pointers)

Tap me (touch)

API ​

oas-hover-card ​

Attributes ​

AttributeDescriptionTypeDefault
append-toMount point (portal): body or a CSS selector. When open and set, the card moves into an isolated shadow inside the target container (styles stay scoped) while keeping position: fixed viewport coordinates — no coordinate translation — escaping clipping contexts such as overflow: hidden / transform; when unset the card stays in the component's own shadowstring—
arrowWhether to show the arrow, default true; arrow="false" hides it (the arrow element and ::part(arrow) remain)stringtrue
arrow-mergeCorner-merged arrow mode: for -start/-end placements a right triangle merges flush with the panel corner — legs collinear with the panel edges (their strokes continue the panel border band), tip pointing orthogonally toward the anchor; the matching corner radius is zeroed; no effect for centered placementsboolean—
arrow-point-at-centerPoint the arrow at the trigger center (keeps pointing at the anchor after viewport clamping); by default the arrow stays at the panel centerboolean—
auto-adjust-overflowAuto-adjust at viewport edges (flip/clamp), default true; "false" disables it and positions strictly per the declared placement (the popup may overflow the viewport)stringtrue
close-delayClose delay in ms, separate from open-delay; falls back to the delay alias, then to 150——
collision-boundaryCustom collision boundary (selector string, first match in multi-ancestor scenes; the collisionBoundary property accepts an element directly): flips and clamps against that element's rect instead of the viewportElement | null—
collision-paddingViewport clamping padding in px, default 4——
contentContent textstring—
delayShow/hide delay in ms, legacy alias: applies to both open and close when open-delay/close-delay are unset; individual values win when set——
disabledDisable the popup: hover/focus triggers no longer open it; the controlled open attribute still worksboolean—
fallback-placementsCustom fallback sequence (comma-separated bases, e.g. left,top): tried in order when the requested placement lacks space; defaults to flipping to the opposite side——
groupDelay group name: components sharing the same group value share delays — moving between members skips the open-delay (opens immediately) and closes the previous one immediately——
hide-when-detachedHide the card when the anchor is fully scrolled out of the viewport; keeps the open state and restores automatically when scrolled backboolean—
offsetMain-axis distance in px (gap between popup and trigger), default 8——
openControlled display (boolean attribute; shows when present)boolean—
open-delayOpen delay in ms, separate from close-delay; falls back to the delay alias, then to 300——
placementPopup placement, 12 directions: top/bottom/left/right × start/center/end (e.g. bottom-start)stringtop
skiddingCross-axis offset in px, shifts along the axis perpendicular to the main axis——
stickyScroll stickiness: partial (default) repositions with the anchor on scroll and hides per hide-when-detached once the anchor leaves the viewport (or clamps to the viewport edge when not enabled); always pins the card to the viewport edge once the anchor scrolls out (stays visible); off disables scroll repositioningstringpartial
titleTitle text (rendered into the visible title region; absorbed from the host on read so no native hover tooltip remains; pass an empty string to clear); use slot="title" for rich contentstring—
widthWidth customization: number (px) or trigger/target (same width as the trigger); falls back to CSS min-width——

Events ​

EventDescription
oas-open-changeDispatched when the open state changes, detail: { open }

Slots ​

NameDescription
defaultTrigger (first non-slot="content" child), triggered on hover/focus
contentRich content slot: free-form HTML preview inside the card (links/buttons etc., interactive)
titleRich title content slot, overrides the title attribute text when present

CSS Variables ​

CSS VariableDefault
--oas-glass-blurnone
--oas-glass-ringtransparent
--oas-hover-card-arrow-height12px
--oas-hover-card-arrow-radius0
--oas-hover-card-arrow-width12px

Released under the MIT OR Apache-2.0 License.