Primitive
Pagination Hybrid
Page navigation for paginated lists, search results, and tables. Numbered links with prev/next arrows; an optional simple variant collapses to "Page N of M".
About
Overview
Pagination splits a long list into pages so users don't scroll forever. Use it for: search results, data tables, blog post archives, anywhere users navigate by page rather than by infinite scroll. The current page is marked with aria-current="page"; prev/next are disabled at the boundaries.
Pagination vs infinite scroll. Use Pagination when users need to jump back ("page 3"), bookmark a position, or share a URL pointing at a specific page. Use infinite scroll for feed-like content where order rarely matters and users browse forward.
Live
Demo
<nav class="ren-pagination" aria-label="Search results pagination">
<a class="ren-pagination-prev" href="?page=2" aria-label="Previous page">‹ Prev</a>
<a class="ren-pagination-item" href="?page=1">1</a>
<a class="ren-pagination-item" href="?page=2">2</a>
<a class="ren-pagination-item" href="?page=3" aria-current="page">3</a>
<a class="ren-pagination-item" href="?page=4">4</a>
<span class="ren-pagination-ellipsis" aria-hidden="true">…</span>
<a class="ren-pagination-item" href="?page=42">42</a>
<a class="ren-pagination-next" href="?page=4" aria-label="Next page">Next ›</a>
</nav>
Shapes
Variants
Reference
API
| Class | Effect |
|---|---|
.ren-pagination | Wrapping <nav>. Inline-flex row of links. |
.ren-pagination-item | One numbered page link. Square, 44 px touch target. |
.ren-pagination-prev / -next | The previous / next arrow links. |
.ren-pagination-ellipsis | The "…" between distant page numbers. Decorative — mark aria-hidden. |
.ren-pagination-simple | Compact variant — just prev / current label / next, for contexts with little room. |
[aria-current="page"] | Marks the current page. Solid accent fill, not a link visually. |
[aria-disabled="true"] | Marks prev/next at the boundaries. Lower opacity, not interactive. |
Inclusive by default
Accessibility
- Wrap in
<nav aria-label="…">with a label that describes what's being paginated ("Search results pagination"). - Mark the current page with
aria-current="page". Don't link it. - Boundary disable: at page 1,
prevgetsaria-disabled="true"and nohref. Same fornexton the last page. - Touch targets: each link is at least 44×44 px. Don't shrink them on mobile — small targets fail Fitts.
Patterns
Examples
Server-rendered pagination
<nav class="ren-pagination" aria-label="Posts pagination">
<a class="ren-pagination-prev" href="/posts?page=<%= currentPage - 1 %>"
<%= currentPage === 1 ? 'aria-disabled="true"' : '' %>>‹ Prev</a>
<% for (const p of visiblePages) { %>
<a class="ren-pagination-item" href="/posts?page=<%= p %>"
<%= p === currentPage ? 'aria-current="page"' : '' %>><%= p %></a>
<% } %>
<a class="ren-pagination-next" href="/posts?page=<%= currentPage + 1 %>"
<%= currentPage === totalPages ? 'aria-disabled="true"' : '' %>>Next ›</a>
</nav>