Hover Card

For sighted users to preview content available behind a link.

Features

  • Can be controlled or uncontrolled.
  • Customize side, alignment, offsets, collision handling.
  • Optionally render a pointing arrow.
  • Supports custom open and close delays.
  • Opens on hover only.
  • Ignored by screen readers.

Install the component from your command line.

npm install @radix-ui/react-hover-card

Import the components and piece the parts together.

import * as HoverCard from '@radix-ui/react-hover-card';
export default () => (
<HoverCard.Root>
<HoverCard.Trigger />
<HoverCard.Content>
<HoverCard.Arrow />
</HoverCard.Content>
</HoverCard.Root>
);

Create your styled hover card component from the primitive parts.

import { styled } from 'path-to/stitches.config';
import * as HoverCard from '@radix-ui/react-hover-card';
const StyledContent = styled(HoverCard.Content, {
borderRadius: 3,
padding: '20px',
fontSize: 14,
backgroundColor: 'gainsboro',
color: 'black',
});
const StyledArrow = styled(HoverCard.Arrow, {
fill: 'gainsboro',
});
export default () => (
<HoverCard.Root>
<HoverCard.Trigger href="http://twitter.com/twitter">
@twitter
</HoverCard.Trigger>
<StyledContent side="top" sideOffset={5}>
<dl>
<dt>Bio</dt>
<dd>What's happening?!</dd>
<dt>Following</dt>
<dd>35</dd>
<dt>Followers</dt>
<dd>59.5M</dd>
</dl>
<StyledArrow />
</StyledContent>
</HoverCard.Root>
);

Contains all the parts of a hover card.

PropTypeDefault
defaultOpenbooleanNo default value
openbooleanNo default value
onOpenChangefunctionNo default value
openDelaynumber700
closeDelaynumber300

The link that opens the hover card when hovered.

PropTypeDefault
asenuma

The component that pops out when the hover card is open.

PropTypeDefault
asenumdiv
forceMountbooleanNo default value
portalledbooleantrue
sideenum"bottom"
sideOffsetnumber0
alignenum"center"
alignOffsetnumber0
avoidCollisionsbooleantrue
collisionToleranceboolean0

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.

PropTypeDefault
asenumsvg
widthnumber10
heightnumber5
offsetnumberNo default value

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.

const scaleIn = keyframes({
'0%': { opacity: 0, transform: 'scale(0)' },
'100%': { opacity: 1, transform: 'scale(1)' },
});
const StyledContent = styled(HoverCard.Content, {
transformOrigin: 'var(--radix-hover-card-content-transform-origin)',
animation: `${scaleIn} 0.5s ease-out`,
});

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.

const slideDown = keyframes({
'0%': { opacity: 0, transform: 'translateY(-10px)' },
'100%': { opacity: 1, transform: 'translateY(0)' },
});
const slideUp = keyframes({
'0%': { opacity: 0, transform: 'translateY(10px)' },
'100%': { opacity: 1, transform: 'translateY(0)' },
});
const StyledContent = styled(HoverCard.Content, {
'&[data-side="top"]': { animationName: slideUp },
'&[data-side="bottom"]': { animationName: slideDown },
animationDuration: '0.6s',
animationTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)',
});

Use the openDelay prop to control the time it takes for the hover card to open.

import { styled } from 'path-to/stitches.config';
import * as HoverCard from '@radix-ui/react-hover-card';
import { BlendingModeIcon } from '@radix-ui/react-icons';
const StyledContent = styled(HoverCard.Content, {
borderRadius: 3,
padding: '20px',
fontSize: 14,
backgroundColor: 'gainsboro',
color: 'black',
});
const StyledArrow = styled(HoverCard.Arrow, {
fill: 'gainsboro',
});
export default () => (
<HoverCard.Root openDelay={0}>
<HoverCard.Trigger href="http://twitter.com/twitter">
@twitter
</HoverCard.Trigger>
<StyledContent side="top" sideOffset={5}>
<dl>
<dt>Bio</dt>
<dd>What's happening?!</dd>
<dt>Following</dt>
<dd>35</dd>
<dt>Followers</dt>
<dd>59.5M</dd>
</dl>
<StyledArrow />
</StyledContent>
</HoverCard.Root>
);

The hover card is intended for mouse users only so will not respond to keyboard navigation.