For sighted users to preview content available behind a link.
import React from 'react';
import * as HoverCard from '@radix-ui/react-hover-card';
import './styles.css';
const HoverCardDemo = () => (
<HoverCard.Root>
<HoverCard.Trigger asChild>
<a
className="ImageTrigger"
href="https://twitter.com/radix_ui"
target="_blank"
rel="noreferrer noopener"
>
<img
className="Image normal"
src="https://pbs.twimg.com/profile_images/1337055608613253126/r_eiMp2H_400x400.png"
alt="Radix UI"
/>
</a>
</HoverCard.Trigger>
<HoverCard.Portal>
<HoverCard.Content className="HoverCardContent" sideOffset={5}>
<div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
<img
className="Image large"
src="https://pbs.twimg.com/profile_images/1337055608613253126/r_eiMp2H_400x400.png"
alt="Radix UI"
/>
<div style={{ display: 'flex', flexDirection: 'column', gap: 15 }}>
<div>
<div className="Text bold">Radix</div>
<div className="Text faded">@radix_ui</div>
</div>
<div className="Text">
Components, icons, colors, and templates for building high-quality, accessible UI.
Free and open-source.
</div>
<div style={{ display: 'flex', gap: 15 }}>
<div style={{ display: 'flex', gap: 5 }}>
<div className="Text bold">0</div> <div className="Text faded">Following</div>
</div>
<div style={{ display: 'flex', gap: 5 }}>
<div className="Text bold">2,900</div> <div className="Text faded">Followers</div>
</div>
</div>
</div>
</div>
<HoverCard.Arrow className="HoverCardArrow" />
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard.Root>
);
export default HoverCardDemo;
Install the component from your command line.
npm install @radix-ui/react-hover-card
Import all parts and piece them together.
import * as HoverCard from '@radix-ui/react-hover-card';
export default () => (
<HoverCard.Root>
<HoverCard.Trigger />
<HoverCard.Portal>
<HoverCard.Content>
<HoverCard.Arrow />
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard.Root>
);
Contains all the parts of a hover card.
Prop | Type | Default |
---|---|---|
defaultOpen | boolean | |
open | boolean | |
onOpenChange | function | |
openDelay | number | 700 |
closeDelay | number | 300 |
The link that opens the hover card when hovered.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
Data Attribute | Values |
---|---|
[data-state] | "open" | "closed" |
When used, portals the content part into the body
.
Prop | Type | Default |
---|---|---|
forceMount | boolean | |
container | HTMLElement | document.body |
The component that pops out when the hover card is open.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
forceMount | boolean | |
side | enum | "bottom" |
sideOffset | number | 0 |
align | enum | "center" |
alignOffset | number | 0 |
avoidCollisions | boolean | true |
collisionBoundary | Boundary | [] |
collisionPadding | number | Padding | 0 |
arrowPadding | number | 0 |
sticky | enum | "partial" |
hideWhenDetached | boolean | false |
Data Attribute | Values |
---|---|
[data-state] | "open" | "closed" |
[data-side] | "left" | "right" | "bottom" | "top" |
[data-align] | "start" | "end" | "center" |
CSS Variable | Description |
---|---|
--radix-hover-card-content-transform-origin | The transform-origin computed from the content and arrow positions/offsets |
An optional arrow element to render alongside the hover card. This can be used to help visually link the trigger with the HoverCard.Content
. Must be rendered inside HoverCard.Content
.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
width | number | 10 |
height | number | 5 |
Use the openDelay
prop to control the time it takes for the hover card to open.
import * as HoverCard from '@radix-ui/react-hover-card';
export default () => (
<HoverCard.Root openDelay={0}>
<HoverCard.Trigger>…</HoverCard.Trigger>
<HoverCard.Content>…</HoverCard.Content>
</HoverCard.Root>
);
We expose a CSS custom property --radix-hover-card-content-transform-origin
. Use it to animate the content from its computed origin based on side
, sideOffset
, align
, alignOffset
and any collisions.
// index.jsx
import * as HoverCard from '@radix-ui/react-hover-card';
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);
}
}
We expose data-side
and data-align
attributes. Their values will change at runtime to reflect collisions. Use them to create collision and direction-aware animations.
// index.jsx
import * as HoverCard from '@radix-ui/react-hover-card';
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);
}
}
The hover card is intended for mouse users only so will not respond to keyboard navigation.