Components · 컨테이너
Accordion · Disclosure (아코디언·디스클로저)
헤더를 눌러 그 아래 패널을 펼치거나 접는다. FAQ·상세페이지의 긴 콘텐츠를 압축하는 데 적합하다.
정의
헤더를 눌러 그 아래 패널을 펼치거나 접어 긴 콘텐츠를 압축해 보여 주는 컴포넌트다.
Anatomy
| 부위 | 토큰 |
|---|---|
| ① 항목 | 보더 --accordion-border · 모서리 --accordion-radius |
| ② 헤더 버튼 | 패딩 --accordion-header-pad · fg --accordion-header-fg · --text-label |
| ③ 아이콘 | --accordion-icon-fg · 펼침 시 180° 회전 |
| ④ 패널 | fg --accordion-panel-fg · --text-body · 패딩 --accordion-header-pad |
변형
| 변형 | 용도 |
|---|---|
| 다중 펼침(기본) | 여러 항목을 동시에 펼침 — FAQ 목록 |
| 단일 펼침 | 한 번에 하나만 펼쳐 비교에 집중 — 형제 항목은 자동 접힘 |
| Disclosure | 비중 낮은 보조 토글("자세히 보기") — --accordion-* 재사용 + 글자 축소, 주 탐색에는 쓰지 않음 |
상태
| 상태 | 헤더 |
|---|---|
| Default(접힘) | fg --accordion-header-fg · aria-expanded="false" · 아이콘 기본 |
| Hover | bg --color-bg-subtle |
| Expanded(펼침) | aria-expanded="true" · 아이콘 180° 회전 · 패널 표시 |
| Focus | box-shadow: var(--focus-ring) |
| Disabled | opacity: var(--opacity-disabled) + cursor: not-allowed |
Do / Don't
Do
- "펼쳐 보면 되는" 보조 정보(FAQ·상세 규격)에 쓴다.
- 헤더 라벨만 읽고도 안에 무엇이 있는지 알 수 있게 구체적으로 쓴다.
- 아이콘 방향(펼침/접힘)과
aria-expanded상태를 항상 일치시킨다.
Don't
- 반드시 봐야 할 핵심 정보를 아코디언 뒤에 숨기지 말 것(KRDS) — 기본 노출한다.
- 한 항목에 문단 여럿·중첩 아코디언을 넣지 말 것 — 길면 별도 페이지로.
- Disclosure를 탭·아코디언 같은 주 탐색 자리에 쓰지 말 것 — 보조 토글로만.
콘텐츠 규칙
- 헤더는 내용을 요약한 명사구·질문 1줄(≤20자) — "항목 1" 같은 무정보 라벨 금지.
- 패널 본문은 2~5문장 안에서 끝낸다 — 더 길면 문서 섹션으로.
- FAQ는 질문형 헤더("배송은 얼마나 걸리나요?") + 답변 본문 구조로 통일한다.
키보드 인터랙션
| 키 | 동작 |
|---|---|
Tab | 다음 아코디언 헤더로 포커스 이동 |
Enter / Space | 포커스된 헤더의 패널 펼침/접힘 토글 |
접근성
- 헤더는 네이티브
<button>—aria-expanded(true/false) +aria-controls(패널 id). 패널은role="region"·aria-labelledby(헤더 id) 권장. - 헤딩 구조 안에서는 헤더 버튼을
<h3>등으로 감싸 문서 아웃라인을 유지한다. - 상태를 아이콘 회전만으로 두지 말고
aria-expanded로 스크린리더에 전달한다. - 헤더 전체가 클릭 대상 ≥
--target-min. 기준:../guidelines/accessibility.md.
코드
홈페이지에서 상담을 신청하면 담당자가 필요한 디자인 범위를 확인해 월 정액 요금을 안내합니다.
노면표시·안전표지를 정기 점검하고 마모되면 교체까지 정액으로 관리합니다.
html
<div class="pi-accordion">
<div class="pi-accordion__item">
<h3 class="pi-accordion__heading">
<button class="pi-accordion__header" type="button" aria-expanded="true" aria-controls="acc-sub" id="acc-sub-h">디자인구독은 어떻게 신청하나요?<svg class="pi-accordion__icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M4 6l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></button>
</h3>
<div class="pi-accordion__panel" role="region" id="acc-sub" aria-labelledby="acc-sub-h">
<p>홈페이지에서 상담을 신청하면 담당자가 필요한 디자인 범위를 확인해 월 정액 요금을 안내합니다.</p>
</div>
</div>
<div class="pi-accordion__item">
<h3 class="pi-accordion__heading">
<button class="pi-accordion__header" type="button" aria-expanded="false" aria-controls="acc-safe" id="acc-safe-h">안전시설관리 구독은 무엇을 관리하나요?<svg class="pi-accordion__icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true"><path d="M4 6l4 4 4-4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></button>
</h3>
<div class="pi-accordion__panel" role="region" id="acc-safe" aria-labelledby="acc-safe-h" hidden>
<p>노면표시·안전표지를 정기 점검하고 마모되면 교체까지 정액으로 관리합니다.</p>
</div>
</div>
</div>css
.pi-accordion__item { border: var(--border-thin) solid var(--accordion-border); border-radius: var(--accordion-radius); }
.pi-accordion__item + .pi-accordion__item { margin-top: var(--space-3); }
.pi-accordion__heading { margin: 0; }
.pi-accordion__header {
display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
width: 100%;
padding: var(--accordion-header-pad);
border: none; background: none; cursor: pointer; text-align: left;
color: var(--accordion-header-fg);
font: var(--text-label);
letter-spacing: var(--text-label-letter-spacing);
min-height: var(--target-min);
word-break: keep-all;
transition: background var(--duration-base) var(--easing-out);
}
.pi-accordion__header:hover { background: var(--color-bg-subtle); }
.pi-accordion__header:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--accordion-radius); }
.pi-accordion__icon { flex: none; color: var(--accordion-icon-fg); transition: transform var(--duration-base) var(--easing-out); }
.pi-accordion__header[aria-expanded="true"] .pi-accordion__icon { transform: rotate(180deg); }
.pi-accordion__panel {
padding: 0 var(--accordion-header-pad) var(--accordion-header-pad);
color: var(--accordion-panel-fg);
font: var(--text-body);
word-break: keep-all;
}
.pi-accordion__panel[hidden] { display: none; }
.pi-accordion--disclosure .pi-accordion__item { border: none; border-radius: 0; }
.pi-accordion--disclosure .pi-accordion__header { font: var(--text-body-sm); padding: var(--space-3) 0; }
@media (prefers-reduced-motion: reduce) { .pi-accordion__header, .pi-accordion__icon { transition: none; } }js
document.querySelectorAll(".pi-accordion__header").forEach((header) => {
header.addEventListener("click", () => {
const expanded = header.getAttribute("aria-expanded") === "true";
header.setAttribute("aria-expanded", expanded ? "false" : "true");
document.getElementById(header.getAttribute("aria-controls")).hidden = expanded;
});
});Changelog
| 날짜 | 변경 |
|---|---|
| 2026-07-15 | 문서 계약(10섹션) 적용 — Anatomy 도해·단일/다중 펼침 변형·Disclosure·콘텐츠 규칙·토글 실코드 신설. KRDS 벤치마킹 규격(핵심 정보 숨김 금지) 승계 |