Components · 오버레이
Tooltip (툴팁)
라벨이 없거나 부족한 요소에 짧은 보조 설명을 잠깐 띄우는 오버레이 컴포넌트. 아이콘 버튼·용어 옆 물음표에 쓴다.
정의
요소에 마우스를 올리거나 포커스했을 때 짧은 보조 설명을 잠깐 띄우는 오버레이 컴포넌트다.
Anatomy
| 부위 | 토큰 |
|---|---|
| ① 말풍선(패널) | bg --tooltip-bg · 글자 --tooltip-fg · 모서리 --tooltip-radius · 패딩 --tooltip-pad-y/--tooltip-pad-x |
| ② 꼬리(화살표) | --tooltip-bg와 같은 색으로 트리거를 가리킴(선택) |
| ③ 트리거 | 아이콘 버튼 등, aria-describedby로 말풍선과 연결 |
변형
| 변형 | 용도 |
|---|---|
| 위(기본) | 트리거 위쪽 여백이 있을 때 — 대부분의 경우 |
| 아래/좌/우 | 화면 가장자리라 위쪽이 잘릴 때 방향 전환 |
| 꼬리 없음 | 조밀한 UI에선 꼬리를 생략하고 말풍선만 |
상태
| 상태 | 규칙 |
|---|---|
| 숨김(기본) | opacity: 0 + 포인터 이벤트 없음 |
| 표시(hover/focus) | 트리거 hover 또는 :focus-visible 시 opacity: 1 |
| 전환 | 표시 시 --duration-base로 페이드(모션 감소 시 즉시) |
Do / Don't
Do
- 아이콘만 있는 버튼에는 툴팁이나
aria-label중 하나를 반드시 붙인다. - hover와
focus둘 다에서 뜨게 한다 — 키보드 사용자도 볼 수 있어야 한다. - 내용은 150자 안팎의 한 조각 정보로 짧게 유지한다.
Don't
- 폼 규칙·필수 안내 같은 꼭 필요한 정보를 툴팁에 숨기지 말 것 — 항상 보이는 헬프텍스트로.
- 툴팁 안에 링크·버튼을 넣지 말 것 — 포커스가 갈 수 없다(그건 Popover의 몫).
title속성과aria-describedby를 함께 쓰지 말 것 — 스크린리더가 중복 낭독한다.
콘텐츠 규칙
- 한 조각 정보만 — 명사구 또는 짧은 한 문장(150자 이내), 줄바꿈 최소화.
- 트리거 라벨을 그대로 반복하지 않는다(버튼이 "인증"이면 툴팁은 인증의 의미를 보탠다).
- 마침표는 완전한 문장일 때만 — 명사구엔 붙이지 않는다.
- 전역 규칙:
../guidelines/ux-writing.md.
키보드 인터랙션
| 키 | 동작 |
|---|---|
Tab | 트리거에 포커스가 오면 툴팁 표시, 벗어나면 숨김 |
Esc | 표시된 툴팁 닫기(선택 — JS로 구현 시, 포커스는 트리거에 유지) |
접근성
- 트리거와 말풍선을
aria-describedby(트리거) ↔id(말풍선,role="tooltip")로 연결한다. title속성과 중복 사용 금지 — 스크린리더 이중 낭독을 유발한다.- hover뿐 아니라
:focus-visible에서도 반드시 표시(키보드 접근). - 대비:
--tooltip-fg(inverse) on--tooltip-bg(navy)는 AA 확보값 — 임의 변경 금지. - 필수 정보는 툴팁이 아니라 항상 보이는 텍스트로(툴팁은 보조 전용).
- 기준:
../guidelines/accessibility.md.
코드
GREENGUARD GOLD(UL 2818) 인증 친환경 라텍스 잉크로 인쇄합니다.
html
<span class="pi-tooltip">
<button class="pi-tooltip__trigger" type="button" aria-describedby="tip-cert" aria-label="인증 정보">?</button>
<span class="pi-tooltip__bubble" id="tip-cert" role="tooltip">
GREENGUARD GOLD(UL 2818) 인증 친환경 라텍스 잉크로 인쇄합니다.
</span>
</span>css
.pi-tooltip { position: relative; display: inline-flex; }
.pi-tooltip__trigger {
display: inline-flex; align-items: center; justify-content: center;
min-width: var(--target-min); min-height: var(--target-min);
border: var(--border-thin) solid var(--color-border-strong);
border-radius: var(--radius-full);
background: var(--color-bg-canvas); color: var(--color-text-secondary);
font: var(--text-label); cursor: pointer;
}
.pi-tooltip__trigger:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.pi-tooltip__bubble {
position: absolute; bottom: calc(100% + var(--space-3)); left: 50%;
transform: translateX(-50%);
min-width: max-content; max-width: 18rem;
padding: var(--tooltip-pad-y) var(--tooltip-pad-x);
border-radius: var(--tooltip-radius);
background: var(--tooltip-bg); color: var(--tooltip-fg);
font: var(--text-caption); line-height: var(--font-lh-normal);
text-align: left; word-break: keep-all;
opacity: 0; pointer-events: none;
transition: opacity var(--duration-base) var(--easing-out);
}
.pi-tooltip__bubble::after {
content: ""; position: absolute; top: 100%; left: 50%;
transform: translateX(-50%);
border: var(--space-2) solid transparent;
border-top-color: var(--tooltip-bg);
}
.pi-tooltip__trigger:hover + .pi-tooltip__bubble,
.pi-tooltip__trigger:focus-visible + .pi-tooltip__bubble { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
.pi-tooltip__bubble { transition: none; }
}Changelog
| 날짜 | 변경 |
|---|---|
| 2026-07-15 | 문서 계약(10섹션) 적용 — KRDS 벤치마킹 규격(2026-07-15) 승계, Anatomy 도해·변형·상태·콘텐츠 규칙·키보드·CSS 전용 실코드 신설 |