Hover Card
Hover Card
링크 뒤에 있는 콘텐츠를 미리 볼 수 있게 해 주는, 시력 사용자를 위한 컴포넌트예요.
출처: 문서
본문
링크나 요소에 마우스를 올렸을 때 미리보기 카드를 띄워 주는 컴포넌트예요. 주로 사용자 프로필 미리보기 같은 용도에 쓰이며, 시력 사용자를 위한 기능이라 스크린 리더에는 무시돼요.
Features
- 제어(controlled)/비제어(uncontrolled) 방식 모두 지원.
- side, alignment, offset, collision 처리 커스터마이즈.
- 선택적으로 가리키는 화살표(arrow) 렌더링.
- 커스텀 오픈/클로즈 딜레이 지원.
- 스크린 리더가 무시해요.
Anatomy
모든 파트를 임포트해 조립해요.
import { HoverCard } from "radix-ui";
export default () => (
<HoverCard.Root>
<HoverCard.Trigger />
<HoverCard.Portal>
<HoverCard.Content>
<HoverCard.Arrow />
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard.Root>
);
API Reference
Root
호버 카드의 모든 파트를 담아요.
| Prop | Type | Default |
|---|---|---|
defaultOpen |
boolean |
No default value |
open |
boolean |
No default value |
onOpenChange |
function |
No default value |
openDelay |
number |
700 |
closeDelay |
number |
300 |
Trigger
호버하면 호버 카드를 여는 링크예요.
| Prop | Type | Default |
|---|---|---|
asChild |
boolean |
false |
| Data attribute | Values |
|---|---|
[data-state] |
"open" | "closed" |
Portal
사용하면 content 파트를 body로 포털해요.
| Prop | Type | Default |
|---|---|---|
forceMount |
boolean |
No default value |
container |
HTMLElement |
document.body |
Content
호버 카드가 열렸을 때 튀어나오는 컴포넌트예요.
| Prop | Type | Default |
|---|---|---|
asChild |
boolean |
false |
forceMount |
boolean |
No default value |
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 |
--radix-hover-card-content-available-width |
The remaining width between the trigger and the boundary edge |
--radix-hover-card-content-available-height |
The remaining height between the trigger and the boundary edge |
--radix-hover-card-trigger-width |
The width of the trigger |
--radix-hover-card-trigger-height |
The height of the trigger |
Arrow
호버 카드 옆에 렌더링할 수 있는 선택적 화살표 요소예요. 트리거와 HoverCard.Content를 시각적으로 연결해 주는 데 도움을 줘요. HoverCard.Content 안에 렌더링해야 해요.
| Prop | Type | Default |
|---|---|---|
asChild |
boolean |
false |
width |
number |
10 |
height |
number |
5 |
Examples
즉시 표시
openDelay prop으로 호버 카드가 열리는 데 걸리는 시간을 제어해요.
import { HoverCard } from "radix-ui";
export default () => (
<HoverCard.Root openDelay={0}>
<HoverCard.Trigger>…</HoverCard.Trigger>
<HoverCard.Content>…</HoverCard.Content>
</HoverCard.Root>
);
콘텐츠 크기 제한
콘텐츠의 너비를 트리거 너비에 맞추고 싶을 수 있어요. 높이를 뷰포트에 넘지 않게 제한할 수도 있어요.
--radix-hover-card-trigger-width, --radix-hover-card-content-available-height 같은 여러 CSS 커스텀 프로퍼티가 이를 지원해요. 콘텐츠 크기를 제한하는 데 활용하세요.
// 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);
}
Origin 인지 애니메이션
--radix-hover-card-content-transform-origin CSS 커스텀 프로퍼티를 노출해요. side, sideOffset, align, alignOffset과 충돌을 기반으로 계산된 origin에서 콘텐츠를 애니메이션하는 데 사용하세요.
// 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);
}
}
Collision 인지 애니메이션
data-side와 data-align 속성을 노출해요. 이 값들은 충돌을 반영해 런타임에 바뀌어요. 충돌과 방향에 인지된 애니메이션을 만드는 데 사용하세요.
// 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);
}
}
Accessibility
호버 카드는 시력 사용자만을 위한 것이며, 콘텐츠는 키보드 사용자에게 접근 불가능해요.
키보드 상호작용
| Key | Description |
|---|---|
Tab |
Opens/closes the hover card. |
Enter |
Opens the hover card link |
더 알아보기 (Learn more)
- Hover Card는 스크린 리더가 무시하고 키보드 사용자에게도 접근 불가능하므로, 필수 정보는 카드에만 담지 않아야 해요.
openDelay/closeDelay로 호버 시 표시되는 타이밍을 조절할 수 있어요.