본문 바로가기

Components · 내비게이션

Pagination (페이지네이션)

긴 목록을 여러 페이지로 나눠 탐색하는 내비게이션 컴포넌트. 안전표지 700종 카탈로그 같은 대량 목록 UI에 쓴다.

정의

긴 목록을 여러 페이지로 나눠 앞뒤·특정 페이지로 이동하게 하는 내비게이션 컴포넌트다.

Anatomy

1 2 3 35 ① 이전/다음 ③ 현재 페이지 ② 페이지 번호 ④ 생략(…)
부위토큰
① 이전/다음 버튼크기 --pagination-size(44) · 모서리 --pagination-radius · 글자 --pagination-fg, 첫/끝 페이지에서 disabled
② 페이지 번호크기 --pagination-size · 글자 --pagination-fg
③ 현재 페이지bg --pagination-bg-current · 글자 --pagination-fg-current · aria-current="page"(링크 아님)
④ 생략(…)페이지가 많을 때 중간을 접는 비인터랙티브 텍스트

변형

변형용도
번호형(기본)페이지 수가 적당할 때(약 10쪽 이하) 번호를 전부 노출
생략형페이지가 많을 때(카탈로그 700종 등) 처음·끝·현재 주변만 + 생략(…)
간이형번호 없이 이전/다음만 — 모바일·무한스크롤 대체

상태

상태번호 버튼이전/다음현재 페이지
Defaultfg --pagination-fgfg --pagination-fgbg --pagination-bg-current / fg --pagination-fg-current
Hoverbg --color-bg-subtlebg --color-bg-subtle— (현재는 hover 없음)
Focusbox-shadow: var(--focus-ring)동일해당 없음(링크 아님)
Disabledopacity: var(--opacity-disabled) + cursor: not-allowed(첫/끝)

Do / Don't

Do
  • 이전·다음 + 숫자 + 현재 페이지 강조를 함께 제공한다 — 지금 어디인지 바로 알게.
  • 항목이 20개 이상일 때만 쓴다(700종 안전표지 카탈로그 등) — 그 미만은 한 화면에 전부 보인다.
  • 페이지가 많으면 처음·끝·현재 주변만 남기고 생략(…)으로 접는다.
Don't
  • 20개 미만 목록에 페이지네이션을 붙이지 말 것 — 전체 표시가 더 빠르다(KRDS 권장).
  • 현재 페이지를 클릭 가능한 링크로 두지 말 것 — 이동할 곳이 없다(aria-current로 표시).
  • 터치 타겟을 44px 미만으로 줄이지 말 것 — 손가락·저시력 접근성 미달.

콘텐츠 규칙

  • 이전/다음이 아이콘만일 때도 aria-label("이전 페이지"·"다음 페이지")을 반드시 준다.
  • 페이지 번호는 아라비아 숫자만 — "1페이지"처럼 단위를 붙이지 않는다.
  • 총 개수를 함께 보이면 "총 700종" 형식으로(숫자 뒤 단위 붙임).
  • 전역 규칙: ../guidelines/ux-writing.md.

키보드 인터랙션

동작
Tab페이지 링크·이전/다음으로 순차 이동(포커스 링 표시)
Enter포커스된 페이지로 이동

접근성

  • <nav aria-label="페이지네이션"> 안에 <ol>·<li> 목록으로 구성한다.
  • 현재 페이지 항목에 aria-current="page" — 스크린리더가 위치를 알린다.
  • 각 버튼 히트영역 ≥ --pagination-size(44px = --target-min).
  • 이전/다음은 아이콘만일 때 aria-label 필수, 첫/끝에서 disabled(또는 aria-disabled).
  • 기준: ../guidelines/accessibility.md.

코드

html
<nav class="pi-pagination" aria-label="페이지네이션">
  <ol class="pi-pagination__list">
    <li><a class="pi-pagination__link pi-pagination__link--nav" href="?page=1" aria-label="이전 페이지">&#8249;</a></li>
    <li><a class="pi-pagination__link" href="?page=1">1</a></li>
    <li><span class="pi-pagination__link pi-pagination__current" aria-current="page">2</span></li>
    <li><a class="pi-pagination__link" href="?page=3">3</a></li>
    <li><span class="pi-pagination__ellipsis" aria-hidden="true">&#8230;</span></li>
    <li><a class="pi-pagination__link" href="?page=35">35</a></li>
    <li><a class="pi-pagination__link pi-pagination__link--nav" href="?page=3" aria-label="다음 페이지">&#8250;</a></li>
  </ol>
</nav>
css
.pi-pagination__list {
  display: flex; align-items: center; gap: var(--space-2);
  list-style: none; margin: 0; padding: 0;
}
.pi-pagination__link {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--pagination-size); min-height: var(--pagination-size);
  padding: 0 var(--space-3);
  border-radius: var(--pagination-radius);
  color: var(--pagination-fg);
  font: var(--text-label);
  text-decoration: none; word-break: keep-all;
  transition: background var(--duration-base) var(--easing-out);
}
a.pi-pagination__link:hover { background: var(--color-bg-subtle); }
a.pi-pagination__link:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.pi-pagination__current {
  background: var(--pagination-bg-current);
  color: var(--pagination-fg-current);
  font-weight: var(--font-weight-bold);
}
.pi-pagination__ellipsis {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--pagination-size); min-height: var(--pagination-size);
  color: var(--color-text-faint);
}
.pi-pagination__link--nav[aria-disabled="true"],
.pi-pagination__link--nav:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
  .pi-pagination__link { transition: none; }
}

Changelog

날짜변경
2026-07-15문서 계약(10섹션) 적용 — KRDS 벤치마킹 규격(2026-07-15) 승계, Anatomy 도해·변형·상태·콘텐츠 규칙·키보드·실코드 신설