|$ curl https://forge-ai.dev/api/markdown?path=docs/components/pagination
$cat docs/pagination.md
updated Recently·16 min read·published

Pagination

CSSHTMLTailwindBootstrapUINavigationIntermediate🎯Free Tools
Introduction

Pagination breaks large datasets into manageable chunks and gives users predictable navigation across pages. This guide covers production-ready pagination patterns in plain HTML/CSS, Tailwind CSS, and Bootstrap — numbered pages, ellipsis truncation, prev/next, sizes, dot indicators, load-more, and jump inputs.

info

Wrap every pagination control in a real <nav aria-label="Pagination"> element. Mark the active page with aria-current="page"so screen readers announce the user's position without relying on color alone.
Numbered Pages

Standard numbered pagination with the active page highlighted in green. Prev and next arrow buttons use inline SVG chevrons and disable at boundaries.

numbered
Live
untitled.html
HTML
1<nav class="pagination" aria-label="Pagination">
2 <button class="page-btn" disabled aria-label="Previous page">
3 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
4 <polyline points="15 18 9 12 15 6"/>
5 </svg>
6 </button>
7 <button class="page-btn">
8 1
9 </button>
10 <button class="page-btn active" aria-current="page">
11 2
12 </button>
13 <button class="page-btn">
14 3
15 </button>
16 <button class="page-btn">
17 4
18 </button>
19 <button class="page-btn">
20 5
21 </button>
22 <button class="page-btn" aria-label="Next page">
23 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
24 <polyline points="9 18 15 12 9 6"/>
25 </svg>
26 </button>
27</nav>
preview
Ellipsis Truncation

When total pages exceed a threshold, replace middle page numbers with an ellipsis. Show the first page, last page, and neighbors of the current page to keep the control compact.

with-ellipsis
Live
untitled.html
HTML
1<nav class="pagination" aria-label="Pagination">
2 <button class="page-btn" disabled aria-label="Previous">
3 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
4 <polyline points="15 18 9 12 15 6"/>
5 </svg>
6 </button>
7 <button class="page-btn">
8 1
9 </button>
10 <span class="page-ellipsis" aria-hidden="true">
11 ···
12 </span>
13 <button class="page-btn">
14 7
15 </button>
16 <button class="page-btn">
17 8
18 </button>
19 <button class="page-btn active" aria-current="page">
20 9
21 </button>
22 <button class="page-btn">
23 10
24 </button>
25 <button class="page-btn">
26 11
27 </button>
28 <span class="page-ellipsis" aria-hidden="true">
29 ···
30 </span>
31 <button class="page-btn">
32 24
33 </button>
34 <button class="page-btn" aria-label="Next">
35 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
36 <polyline points="9 18 15 12 9 6"/>
37 </svg>
38 </button>
39</nav>
preview
Prev / Next Cards

Minimal prev/next navigation for articles, blog posts, and sequential content. Each card shows the adjacent item title and a direction label.

prev-next
Live
untitled.html
HTML
1<div class="prev-next-wrap">
2 <a href="#" class="pn-card pn-prev">
3 <span class="pn-label">
4 ← Previous
5 </span>
6 <span class="pn-title">
7 Getting Started with CSS Grid
8 </span>
9 </a>
10 <a href="#" class="pn-card pn-next">
11 <span class="pn-label">
12 Next →
13 </span>
14 <span class="pn-title">
15 Advanced Flexbox Techniques
16 </span>
17 </a>
18</div>
preview
Sizes

Small, default, and large pagination sizes. Choose the right size based on density — compact for data tables, default for general use, and large for touch targets.

sizes
Live
untitled.html
HTML
1<div class="size-demo">
2 <nav class="pagination sm" aria-label="Small">
3 <button class="page-btn">
4 1
5 </button>
6 <button class="page-btn active" aria-current="page">
7 2
8 </button>
9 <button class="page-btn">
10 3
11 </button>
12 <button class="page-btn">
13 4
14 </button>
15 <button class="page-btn">
16 5
17 </button>
18 </nav>
19 <nav class="pagination md" aria-label="Default">
20 <button class="page-btn">
21 1
22 </button>
23 <button class="page-btn active" aria-current="page">
24 2
25 </button>
26 <button class="page-btn">
27 3
28 </button>
29 <button class="page-btn">
30 4
31 </button>
32 <button class="page-btn">
33 5
34 </button>
35 </nav>
36 <nav class="pagination lg" aria-label="Large">
37 <button class="page-btn">
38 1
39 </button>
40 <button class="page-btn active" aria-current="page">
41 2
42 </button>
43 <button class="page-btn">
44 3
45 </button>
46 <button class="page-btn">
47 4
48 </button>
49 <button class="page-btn">
50 5
51 </button>
52 </nav>
53</div>
preview
With Page Info

Displaying "Showing X–Y of Z results" alongside pagination helps users understand their position in the dataset. Essential for data tables, search results, and admin dashboards.

page-info
Live
untitled.html
HTML
1<div class="pagination-info-wrap">
2 <p class="page-info">
3 Showing
4 <strong>
5 11–20
6 </strong>
7 of
8 <strong>
9 247
10 </strong>
11 results
12 </p>
13 <nav class="pagination" aria-label="Pagination">
14 <button class="page-btn" aria-label="Previous">
15 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
16 <polyline points="15 18 9 12 15 6"/>
17 </svg>
18 </button>
19 <button class="page-btn">
20 1
21 </button>
22 <button class="page-btn active" aria-current="page">
23 2
24 </button>
25 <button class="page-btn">
26 3
27 </button>
28 <span class="page-ellipsis" aria-hidden="true">
29 ···
30 </span>
31 <button class="page-btn">
32 25
33 </button>
34 <button class="page-btn" aria-label="Next">
35 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
36 <polyline points="9 18 15 12 9 6"/>
37 </svg>
38 </button>
39 </nav>
40</div>
preview
Dots / Carousel Style

Dot indicators are compact pagination for carousels, image sliders, and onboarding flows. The active dot stretches into a pill shape. A numbered variant shows the current index as a badge.

dots-style
Live
untitled.html
HTML
1<div class="dots-demo">
2 <div class="dots-wrap">
3 <button class="dot" aria-label="Slide 1">
4 </button>
5 <button class="dot active" aria-label="Slide 2" aria-current="true">
6 </button>
7 <button class="dot" aria-label="Slide 3">
8 </button>
9 <button class="dot" aria-label="Slide 4">
10 </button>
11 <button class="dot" aria-label="Slide 5">
12 </button>
13 </div>
14 <div class="dots-wrap labels">
15 <button class="dot-label">
16 1
17 </button>
18 <button class="dot-label active">
19 2
20 </button>
21 <button class="dot-label">
22 3
23 </button>
24 <button class="dot-label">
25 4
26 </button>
27 <button class="dot-label">
28 5
29 </button>
30 </div>
31</div>
preview
Minimal Bare Style

Borderless, text-only pagination for lightweight contexts. No backgrounds or borders — just colored text with a subtle hover underline. Works well inside cards, modals, and inline content.

minimal-bare
Live
untitled.html
HTML
1<nav class="pagination minimal" aria-label="Pagination">
2 <a href="#" class="page-link prev" aria-label="Previous">
3 ← Prev
4 </a>
5 <span class="page-separator">
6 |
7 </span>
8 <span class="page-current">
9 Page 3 of 12
10 </span>
11 <span class="page-separator">
12 |
13 </span>
14 <a href="#" class="page-link next" aria-label="Next">
15 Next →
16 </a>
17</nav>
preview
Load More Button

For feeds, search results, and infinite-scroll-like experiences, a "Load More" button appends the next batch of items without replacing the current view. This preserves scroll position and avoids the cognitive cost of numbered pagination.

load-more
Live
untitled.html
HTML
1<div class="load-more-demo">
2 <div class="lm-items">
3 <div class="lm-item">
4 <span class="lm-num">
5 1
6 </span>
7 <span class="lm-text">
8 Deploy authentication microservice to staging
9 </span>
10 </div>
11 <div class="lm-item">
12 <span class="lm-num">
13 2
14 </span>
15 <span class="lm-text">
16 Update rate limiting middleware for v2 API
17 </span>
18 </div>
19 <div class="lm-item">
20 <span class="lm-num">
21 3
22 </span>
23 <span class="lm-text">
24 Fix pagination overflow on mobile viewports
25 </span>
26 </div>
27 </div>
28 <div class="lm-footer">
29 <span class="lm-info">
30 Showing 3 of 47 tasks
31 </span>
32 <button class="lm-btn" id="load-more-btn">
33 <span class="lm-btn-text">
34 Load More
35 </span>
36 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
37 <polyline points="6 9 12 15 18 9"/>
38 </svg>
39 </button>
40 </div>
41</div>
preview
Jump to Page Input

For large datasets (100+ pages), a page number input lets users jump directly to a specific page. The input validates bounds and shows the total page count. Essential for admin dashboards and data-heavy UIs.

jump-to-page
Live
untitled.html
HTML
1<div class="jump-demo">
2 <nav class="pagination" aria-label="Pagination">
3 <button class="page-btn" aria-label="Previous">
4 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
5 <polyline points="15 18 9 12 15 6"/>
6 </svg>
7 </button>
8 <button class="page-btn">
9 1
10 </button>
11 <span class="page-ellipsis" aria-hidden="true">
12 ···
13 </span>
14 <button class="page-btn">
15 18
16 </button>
17 <button class="page-btn active" aria-current="page">
18 19
19 </button>
20 <button class="page-btn">
21 20
22 </button>
23 <span class="page-ellipsis" aria-hidden="true">
24 ···
25 </span>
26 <button class="page-btn">
27 52
28 </button>
29 <button class="page-btn" aria-label="Next">
30 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
31 <polyline points="9 18 15 12 9 6"/>
32 </svg>
33 </button>
34 </nav>
35 <div class="jump-input-wrap">
36 <span class="jump-label">
37 Go to
38 </span>
39 <input type="number" class="jump-input" min="1" max="52" value="19" />
40 <span class="jump-total">
41 of 52
42 </span>
43 </div>
44</div>
preview
HTML Structure

Use a <nav> element with aria-label="Pagination". Mark the active page with aria-current="page" and disable prev/next at boundaries with the disabled attribute.

pagination-structure.html
HTML
1<nav class="pagination" aria-label="Pagination">
2 <button class="page-btn" disabled aria-label="Previous">
3 <svg><!-- chevron left --></svg>
4 </button>
5 <button class="page-btn">1</button>
6 <button class="page-btn">2</button>
7 <button class="page-btn active" aria-current="page">3</button>
8 <button class="page-btn">4</button>
9 <button class="page-btn">5</button>
10 <button class="page-btn" aria-label="Next">
11 <svg><!-- chevron right --></svg>
12 </button>
13</nav>
Accessibility

Pagination is a navigation landmark. Treat it as part of the page structure, not just visual chrome.

  • Use a real <nav> element and real <button> elements so screen readers expose the landmark and actionable roles.
  • Provide a visible focus ring on every page button — never remove outline without a replacement that meets 3:1 contrast.
  • Add descriptive aria-label text to prev/next arrow buttons, e.g. aria-label="Previous page".
  • Mark the active page with aria-current="page" so assistive tech announces "current page".
  • Disable boundary prev/next buttons with disabled when on the first or last page, rather than hiding them.
  • Ensure full keyboard support: Tab moves between page buttons and Enter / Space activates them.
Best Practices
  • Use aria-current="page" on the active page for screen reader announcements.
  • Disable prev/next buttons at boundaries rather than hiding them — consistency helps muscle memory.
  • Show total result count and current range alongside pagination controls.
  • For 100+ pages, truncate with ellipsis — showing first, last, and 2–3 neighbors of the current page.
  • On mobile, consider collapsing to prev/next only with a page indicator (e.g., "Page 3 of 12").
  • Sync URL query params (?page=3) so pagination states are shareable and bookmarkable.
  • For datasets under 20 items, consider a "Load More" button instead of traditional numbered pagination.

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.