ページネーション
前後リンクとページ番号のページネーション。現在地は aria-current、省略記号は読み上げ対象外にしています。JavaScript不要。
プレビュー
<nav class="pagination" aria-label="ページネーション">
<ul class="pagination__list">
<li>
<a class="pagination__link pagination__link--edge" href="?page=2" rel="prev">
<span aria-hidden="true">←</span>
<span class="pagination__edge-text">前へ</span>
</a>
</li>
<li><a class="pagination__link" href="?page=1">1</a></li>
<li><a class="pagination__link" href="?page=2">2</a></li>
<li>
<a class="pagination__link" href="?page=3" aria-current="page">3</a>
</li>
<li><a class="pagination__link" href="?page=4">4</a></li>
<li><span class="pagination__ellipsis" aria-hidden="true">…</span></li>
<li><a class="pagination__link" href="?page=12">12</a></li>
<li>
<a class="pagination__link pagination__link--edge" href="?page=4" rel="next">
<span class="pagination__edge-text">次へ</span>
<span aria-hidden="true">→</span>
</a>
</li>
</ul>
</nav>/* このスニペット配下だけ box-sizing を揃える(既存のリセットとは競合しません) */
.pagination,
.pagination *,
.pagination *::before,
.pagination *::after {
box-sizing: border-box;
}
.pagination {
--pagination-size: 40px;
--pagination-gap: 0.375rem;
--pagination-fg: #374151;
--pagination-muted: #9ca3af;
--pagination-border: #e5e7eb;
--pagination-accent: #2563eb;
--pagination-hover: #f3f4f6;
font-size: 0.875rem;
}
.pagination__list {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: var(--pagination-gap);
margin: 0;
padding: 0;
list-style: none;
}
.pagination__link {
display: grid;
place-items: center;
min-width: var(--pagination-size);
height: var(--pagination-size);
padding: 0 0.625rem;
border: 1px solid var(--pagination-border);
border-radius: 8px;
color: var(--pagination-fg);
font-variant-numeric: tabular-nums;
text-decoration: none;
transition: background-color 0.15s, border-color 0.15s, color 0.15s;
}
.pagination__link:hover {
background: var(--pagination-hover);
border-color: var(--pagination-muted);
}
.pagination__link[aria-current="page"] {
background: var(--pagination-accent);
border-color: var(--pagination-accent);
color: #ffffff;
font-weight: 600;
pointer-events: none;
}
.pagination__link--edge {
display: inline-flex;
align-items: center;
gap: 0.375rem;
}
.pagination__ellipsis {
display: grid;
place-items: center;
min-width: var(--pagination-size);
height: var(--pagination-size);
color: var(--pagination-muted);
}
.pagination__link:focus-visible {
outline: 2px solid var(--pagination-accent);
outline-offset: 2px;
}
/* 狭い画面では「前へ / 次へ」の文字を隠して矢印だけにする */
@media (max-width: 480px) {
.pagination {
--pagination-size: 36px;
}
.pagination__edge-text {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
}
@media (prefers-color-scheme: dark) {
.pagination {
--pagination-fg: #e5e7eb;
--pagination-muted: #6b7280;
--pagination-border: #374151;
--pagination-accent: #3b82f6;
--pagination-hover: #1f2937;
}
}
/* ここから下はプレビュー表示用です。コピーして使うときは不要です */
body {
margin: 0;
background: #ffffff;
font-family: system-ui, -apple-system, "Segoe UI", "Hiragino Sans",
"Noto Sans JP", sans-serif;
color: #111827;
}
@media (prefers-color-scheme: dark) {
body {
background: #111827;
color: #f9fafb;
}
}
