Hover Card collision-aware animation example
To create collision and direction-aware animations using data-side attribute:
// index.jsx
import { HoverCard } from "radix-ui";
import "./styles.css";
export default () => (
<HoverCard.Root>
<HoverCard.Trigger>…</HoverCard.Trigger>
<HoverCard.Content className="HoverCardContent">…</HoverCard.Content>
</HoverCard.Root>
);
/* styles.css */
.HoverCardContent {
animation-duration: 0.6s;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.HoverCardContent[data-side="top"] {
animation-name: slideUp;
}
.HoverCardContent[data-side="bottom"] {
animation-name: slideDown;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
Hover Card anatomy and structure
Hover Card is composed of: HoverCard.Root (contains all parts), HoverCard.Trigger (the link that opens on hover), HoverCard.Portal (portals content into body), HoverCard.Content (pops out when open), and HoverCard.Arrow (optional arrow element). The arrow must be rendered inside HoverCard.Content.
Hover Card Root props
HoverCard.Root accepts: defaultOpen (boolean, uncontrolled open state), open (boolean, controlled open state, must be used with onOpenChange), onOpenChange (function called when open state changes), openDelay (number in ms, default 700, time from mouse enter trigger to card opening), closeDelay (number in ms, default 300, time from mouse leaving trigger or content to card closing).
Hover Card Trigger props and data attributes
HoverCard.Trigger accepts: asChild (boolean, default false, changes default rendered element). It supports data attribute [data-state] with values 'open' or 'closed'.
Hover Card Portal props
HoverCard.Portal accepts: forceMount (boolean, forces mounting for animation control, inherited by HoverCard.Content), container (HTMLElement, default document.body, specifies where to portal the content).
Hover Card Content positioning props
HoverCard.Content accepts: side (enum 'top'|'right'|'bottom'|'left', default 'bottom'), sideOffset (number in pixels, default 0, distance from trigger), align (enum 'start'|'center'|'end', default 'center'), alignOffset (number in pixels, default 0, offset from alignment options), avoidCollisions (boolean, default true, overrides side and align to prevent boundary collisions).
Hover Card Content collision and boundary props
HoverCard.Content accepts: collisionBoundary (Element | null | Array<Element | null>, default empty array, element(s) used for collision detection alongside viewport), collisionPadding (number or Partial<Record<Side, number>>, default 0, distance in pixels from boundary edges for collision detection), arrowPadding (number, default 0, padding between arrow and content edges to prevent overflow from border-radius), hideWhenDetached (boolean, default false, hides content when trigger becomes fully occluded).
Hover Card Content sticky behavior
HoverCard.Content sticky prop accepts enum 'partial' or 'always' (default 'partial'). 'partial' keeps content in boundary while trigger is at least partially in boundary. 'always' keeps content in boundary regardless of trigger position.
Hover Card Content data attributes
HoverCard.Content supports data attributes: [data-state] with values 'open' or 'closed', [data-side] with values 'left'|'right'|'bottom'|'top', [data-align] with values 'start'|'end'|'center'.
Hover Card Content CSS variables
HoverCard.Content exposes CSS variables: --radix-hover-card-content-transform-origin (computed from content and arrow positions/offsets), --radix-hover-card-content-available-width (remaining width between trigger and boundary edge), --radix-hover-card-content-available-height (remaining height between trigger and boundary edge), --radix-hover-card-trigger-width (trigger width), --radix-hover-card-trigger-height (trigger height).
Hover Card Arrow props
HoverCard.Arrow accepts: asChild (boolean, default false), width (number in pixels, default 10), height (number in pixels, default 5). Arrow must be rendered inside HoverCard.Content.
Hover Card controlled and uncontrolled API
Hover Card can be uncontrolled using defaultOpen prop on Root. Hover Card can be controlled using open and onOpenChange props on Root.
Hover Card asChild composition
HoverCard.Trigger, HoverCard.Content, and HoverCard.Arrow support the asChild prop to change the default rendered element for a child element, merging their props and behavior.
Hover Card keyboard interactions
Tab key opens/closes the hover card. Enter key opens the hover card link.
Hover Card openDelay example
To make hover card open instantly, set openDelay={0} on HoverCard.Root:
import { HoverCard } from "radix-ui";
export default () => (
<HoverCard.Root openDelay={0}>
<HoverCard.Trigger>…</HoverCard.Trigger>
<HoverCard.Content>…</HoverCard.Content>
</HoverCard.Root>
);
Hover Card content size constraint example
To constrain content width to trigger width and height to available viewport height, use CSS custom properties:
// index.jsx
import { HoverCard } from "radix-ui";
import "./styles.css";
export default () => (
<HoverCard.Root>
<HoverCard.Trigger>…</HoverCard.Trigger>
<HoverCard.Portal>
<HoverCard.Content className="HoverCardContent" sideOffset={5}>
…
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard.Root>
);
/* styles.css */
.HoverCardContent {
width: var(--radix-hover-card-trigger-width);
max-height: var(--radix-hover-card-content-available-height);
}
Hover Card origin-aware animation example
To animate content from computed origin based on side, sideOffset, align, alignOffset and collisions:
// index.jsx
import { HoverCard } from "radix-ui";
import "./styles.css";
export default () => (
<HoverCard.Root>
<HoverCard.Trigger>…</HoverCard.Trigger>
<HoverCard.Content className="HoverCardContent">…</HoverCard.Content>
</HoverCard.Root>
);
/* styles.css */
.HoverCardContent {
transform-origin: var(--radix-hover-card-content-transform-origin);
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
Hover Card matching trigger size
Position Hover Card content correctly when matching trigger size.
Hover Card text selection improvement
Improve text selection experience in Hover Card.
Hover Card submenu CSS custom properties
Expose new CSS custom properties to enable size constraints in Hover Card.
HoverCard.Portal added for portalling behavior
HoverCard now has a Portal part. To avoid regressions, this part should be used if portalling behavior is desired. Note that z-index is no longer managed, providing full control of layering.
HoverCard.Content collisionPadding prop replaces collisionTolerance
HoverCard.Content's collisionTolerance prop was renamed to collisionPadding and now accepts either a number or a padding object.
HoverCard.Content Arrow offset prop removed
The offset prop was removed from HoverCard.Arrow.
HoverCard.Content new positioning props
HoverCard.Content has new props: collisionBoundary, arrowPadding, sticky, and hideWhenDetached.
Tooltip opens on focus for keyboard support
HoverCard opens on focus to improve keyboard support.
Hover Card version 0.0.1 released
Hover Card primitive was introduced as a new primitive in version 0.0.1.
Hover Card purpose and use case
Hover Card is for sighted users to preview content available behind a link.
Hover Card anatomy
Hover Card consists of three parts: Root (contains all the parts of the hover card), Trigger (wraps the link that will open the hover card), and Content (contains the content of the open hover card, based on the div element).
Hover Card Content size prop values
The Content component accepts a size prop with values 1, 2, and 3 to control the size of the hover card.
Hover Card Content maxWidth prop
The Content component accepts a maxWidth prop to control the maximum width of the hover card content. Common values shown are 240px, 280px, 320px, and 450px.
Hover Card Content width prop
The Content component accepts a width prop to control the exact width of the hover card content.
Hover Card basic example
Example showing a hover card with text trigger, avatar, heading, and description:
```jsx
<Text>
Follow{" "}
<HoverCard.Root>
<HoverCard.Trigger>
<Link href="https://twitter.com/radix_ui" target="_blank">
@radix_ui
</Link>
</HoverCard.Trigger>
<HoverCard.Content maxWidth="300px">
<Flex gap="4">
<Avatar
size="3"
fallback="R"
radius="full"
src="https://pbs.twimg.com/profile_images/1337055608613253126/r_eiMp2H_400x400.png"
/>
<Box>
<Heading size="3" as="h3">
Radix
</Heading>
<Text as="div" size="2" color="gray" mb="2">
@radix_ui
</Text>
<Text as="div" size="2">
React components, icons, and colors for building high-quality,
accessible UI.
</Text>
</Box>
</Flex>
</HoverCard.Content>
</HoverCard.Root>{" "}
for updates.
</Text>
```
Hover Card with image content example
Example showing a hover card with an image on the left side using Inset component:
```jsx
<Text>
Technology revolutionized{" "}
<HoverCard.Root>
<HoverCard.Trigger>
<Link href="#">typography</Link>
</HoverCard.Trigger>
<HoverCard.Content width="450px">
<Flex>
<Box asChild flexShrink="0">
<Inset side="left" pr="current">
<img
src="https://images.unsplash.com/photo-1617050318658-a9a3175e34cb?&auto=format&fit=crop&w=300&q=90"
alt="Bold typography"
style={{
display: "block",
objectFit: "cover",
height: "100%",
width: 150,
backgroundColor: "var(--gray-5)",
}}
/>
</Inset>
</Box>
<Text size="2" as="p">
<Strong>Typography</Strong> is the art and technique of arranging type
to make written language legible, readable and appealing when
displayed. The arrangement of type involves selecting typefaces, point
sizes, line lengths, line-spacing (leading), and letter-spacing
(tracking)…
</Text>
</Flex>
</HoverCard.Content>
</HoverCard.Root>{" "}
in the latter twentieth century.
</Text>
```
Radix Themes 3.0.0 HoverCard and Popover default maxWidth
Radix Themes 3.0.0 set HoverCard and Popover Content parts to have maxWidth="480px" by default.