$ cat docs/pagination.md
updated Recently · 11 min read · published
Pagination Pagination breaks large datasets into manageable pages. These examples cover numbered controls, prev/next buttons, ellipsis truncation, multiple sizes, compact mobile layouts, active state indicators, dot-style carousel pagination, and prev/next cards for sequential content like articles.
Numbered Pages
Standard numbered pagination with the active page highlighted in green. Each page number is a clickable button with clear visual feedback. Prev and next arrow buttons use SVG chevrons and disable at boundaries.
numbered-pagination HTML CSS Live
Copy 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" 4 stroke="currentColor" stroke-width="2" stroke-linecap="round" 5 stroke-linejoin="round"> 6 <polyline points="15 18 9 12 15 6"/> 7 </svg> 8 </button> 9 <button class="page-btn"> 10 1 11 </button> 12 <button class="page-btn active" aria-current="page"> 13 2 14 </button> 15 <button class="page-btn"> 16 3 17 </button> 18 <button class="page-btn"> 19 4 20 </button> 21 <button class="page-btn"> 22 5 23 </button> 24 <button class="page-btn" aria-label="Next page"> 25 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" 26 stroke="currentColor" stroke-width="2" stroke-linecap="round" 27 stroke-linejoin="round"> 28 <polyline points="9 18 15 12 9 6"/> 29 </svg> 30 </button> 31 </nav>
Copy 1 .pagination { 2 display:flex; 3 align-items:center; 4 gap:4px; 5 padding:20px 24px; 6 font-family:system-ui, 7 sans-serif 8 } 9 .page-btn { 10 display:inline-flex; 11 align-items:center; 12 justify-content:center; 13 min-width:36px; 14 height:36px; 15 padding:0 10px; 16 border-radius:8px; 17 border:1px solid #2A2A2A; 18 background:transparent; 19 color:#A0A0A0; 20 font-size:13px; 21 font-weight:500; 22 font-family:system-ui, 23 sans-serif; 24 cursor:pointer; 25 transition:all .2s 26 } 27 .page-btn:hover:not(.active):not(:disabled) { 28 border-color:#3A3A3A; 29 color:#E0E0E0; 30 background:rgba(255, 31 255, 32 255, 33 .03) 34 } 35 .page-btn.active { 36 background:#00FF41; 37 color:#0A0A0A; 38 border-color:#00FF41; 39 font-weight:700 40 } 41 .page-btn:disabled { 42 opacity:.3; 43 cursor:not-allowed 44 } 45 .page-btn svg { 46 flex-shrink:0 47 }
preview
Ellipsis Truncation
When total pages exceed a threshold, replace middle page numbers with an ellipsis character. This shows the first page, last page, and neighbors of the current page to keep the control compact and scannable.
ellipsis-pagination HTML CSS Live
Copy 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" 4 stroke="currentColor" stroke-width="2" stroke-linecap="round" 5 stroke-linejoin="round"> 6 <polyline points="15 18 9 12 15 6"/> 7 </svg> 8 </button> 9 <button class="page-btn"> 10 1 11 </button> 12 <span class="page-ellipsis"> 13 ··· 14 </span> 15 <button class="page-btn"> 16 7 17 </button> 18 <button class="page-btn"> 19 8 20 </button> 21 <button class="page-btn active" aria-current="page"> 22 9 23 </button> 24 <button class="page-btn"> 25 10 26 </button> 27 <button class="page-btn"> 28 11 29 </button> 30 <span class="page-ellipsis"> 31 ··· 32 </span> 33 <button class="page-btn"> 34 24 35 </button> 36 <button class="page-btn" aria-label="Next"> 37 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" 38 stroke="currentColor" stroke-width="2" stroke-linecap="round" 39 stroke-linejoin="round"> 40 <polyline points="9 18 15 12 9 6"/> 41 </svg> 42 </button> 43 </nav>
Copy 1 .pagination { 2 display:flex; 3 align-items:center; 4 gap:4px; 5 padding:20px 24px; 6 font-family:system-ui, 7 sans-serif 8 } 9 .page-btn { 10 display:inline-flex; 11 align-items:center; 12 justify-content:center; 13 min-width:36px; 14 height:36px; 15 padding:0 10px; 16 border-radius:8px; 17 border:1px solid #2A2A2A; 18 background:transparent; 19 color:#A0A0A0; 20 font-size:13px; 21 font-weight:500; 22 font-family:system-ui, 23 sans-serif; 24 cursor:pointer; 25 transition:all .2s 26 } 27 .page-btn:hover:not(.active):not(:disabled) { 28 border-color:#3A3A3A; 29 color:#E0E0E0; 30 background:rgba(255, 31 255, 32 255, 33 .03) 34 } 35 .page-btn.active { 36 background:#00FF41; 37 color:#0A0A0A; 38 border-color:#00FF41; 39 font-weight:700 40 } 41 .page-btn:disabled { 42 opacity:.3; 43 cursor:not-allowed 44 } 45 .page-btn svg { 46 flex-shrink:0 47 } 48 .page-ellipsis { 49 display:inline-flex; 50 align-items:center; 51 justify-content:center; 52 min-width:36px; 53 height:36px; 54 color:#555; 55 font-size:14px; 56 letter-spacing:2px; 57 user-select:none 58 }
preview
Prev / Next Cards
Minimal prev/next navigation for articles, blog posts, and sequential content. Each card shows the adjacent item with its title and a direction label. This is the standard pattern for documentation and blog pagination.
prev-next-pagination HTML CSS Live
Copy 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>
Copy 1 .prev-next-wrap { 2 display:flex; 3 gap:12px; 4 padding:20px 24px; 5 font-family:system-ui, 6 sans-serif 7 } 8 .pn-card { 9 flex:1; 10 display:flex; 11 flex-direction:column; 12 gap:6px; 13 padding:16px; 14 border-radius:8px; 15 border:1px solid #2A2A2A; 16 background:#111; 17 text-decoration:none; 18 transition:all .2s 19 } 20 .pn-card:hover { 21 border-color:#00FF41/30; 22 background:#141420 23 } 24 .pn-prev { 25 align-items:flex-start 26 } 27 .pn-next { 28 align-items:flex-end; 29 text-align:right 30 } 31 .pn-label { 32 font-size:11px; 33 color:#666; 34 text-transform:uppercase; 35 letter-spacing:.5px; 36 font-weight:500 37 } 38 .pn-title { 39 font-size:13px; 40 color:#E0E0E0; 41 font-weight:600; 42 line-height:1.4 43 } 44 .pn-card:hover .pn-title { 45 color:#00FF41 46 }
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 primary page navigation where touch targets matter.
pagination-sizes HTML CSS Live
Copy 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>
Copy 1 .size-demo { 2 display:flex; 3 flex-direction:column; 4 gap:16px; 5 padding:20px 24px; 6 font-family:system-ui, 7 sans-serif 8 } 9 .pagination { 10 display:flex; 11 align-items:center; 12 gap:4px 13 } 14 .pagination.sm .page-btn { 15 min-width:28px; 16 height:28px; 17 padding:0 8px; 18 font-size:11px; 19 border-radius:6px 20 } 21 .pagination.md .page-btn { 22 min-width:36px; 23 height:36px; 24 padding:0 10px; 25 font-size:13px; 26 border-radius:8px 27 } 28 .pagination.lg .page-btn { 29 min-width:44px; 30 height:44px; 31 padding:0 14px; 32 font-size:15px; 33 border-radius:10px 34 } 35 .page-btn { 36 display:inline-flex; 37 align-items:center; 38 justify-content:center; 39 border:1px solid #2A2A2A; 40 background:transparent; 41 color:#A0A0A0; 42 font-weight:500; 43 font-family:system-ui, 44 sans-serif; 45 cursor:pointer; 46 transition:all .2s 47 } 48 .page-btn:hover:not(.active) { 49 border-color:#3A3A3A; 50 color:#E0E0E0; 51 background:rgba(255, 52 255, 53 255, 54 .03) 55 } 56 .page-btn.active { 57 background:#00FF41; 58 color:#0A0A0A; 59 border-color:#00FF41; 60 font-weight:700 61 }
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 with large record sets.
pagination-info HTML CSS Live
Copy 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" 16 stroke="currentColor" stroke-width="2" stroke-linecap="round" 17 stroke-linejoin="round"> 18 <polyline points="15 18 9 12 15 6"/> 19 </svg> 20 </button> 21 <button class="page-btn"> 22 1 23 </button> 24 <button class="page-btn active" aria-current="page"> 25 2 26 </button> 27 <button class="page-btn"> 28 3 29 </button> 30 <span class="page-ellipsis"> 31 ··· 32 </span> 33 <button class="page-btn"> 34 25 35 </button> 36 <button class="page-btn" aria-label="Next"> 37 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" 38 stroke="currentColor" stroke-width="2" stroke-linecap="round" 39 stroke-linejoin="round"> 40 <polyline points="9 18 15 12 9 6"/> 41 </svg> 42 </button> 43 </nav> 44 </div>
Copy 1 .pagination-info-wrap { 2 display:flex; 3 align-items:center; 4 justify-content:space-between; 5 padding:20px 24px; 6 font-family:system-ui, 7 sans-serif; 8 flex-wrap:wrap; 9 gap:12px 10 } 11 .page-info { 12 font-size:12px; 13 color:#808080; 14 margin:0 15 } 16 .page-info strong { 17 color:#E0E0E0; 18 font-weight:600 19 } 20 .pagination { 21 display:flex; 22 align-items:center; 23 gap:4px; 24 margin:0 25 } 26 .page-btn { 27 display:inline-flex; 28 align-items:center; 29 justify-content:center; 30 min-width:36px; 31 height:36px; 32 padding:0 10px; 33 border-radius:8px; 34 border:1px solid #2A2A2A; 35 background:transparent; 36 color:#A0A0A0; 37 font-size:13px; 38 font-weight:500; 39 font-family:system-ui, 40 sans-serif; 41 cursor:pointer; 42 transition:all .2s 43 } 44 .page-btn:hover:not(.active) { 45 border-color:#3A3A3A; 46 color:#E0E0E0; 47 background:rgba(255, 48 255, 49 255, 50 .03) 51 } 52 .page-btn.active { 53 background:#00FF41; 54 color:#0A0A0A; 55 border-color:#00FF41; 56 font-weight:700 57 } 58 .page-btn svg { 59 flex-shrink:0 60 } 61 .page-ellipsis { 62 display:inline-flex; 63 align-items:center; 64 justify-content:center; 65 min-width:36px; 66 height:36px; 67 color:#555; 68 font-size:14px; 69 letter-spacing:2px; 70 user-select:none 71 }
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-pagination HTML CSS JS Live
Copy 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>
Copy 1 .dots-demo { 2 display:flex; 3 flex-direction:column; 4 gap:20px; 5 align-items:center; 6 padding:24px; 7 font-family:system-ui, 8 sans-serif 9 } 10 .dots-wrap { 11 display:flex; 12 gap:10px; 13 align-items:center 14 } 15 .dot { 16 width:10px; 17 height:10px; 18 border-radius:50%; 19 border:none; 20 background:#333; 21 cursor:pointer; 22 padding:0; 23 transition:all .3s 24 } 25 .dot:hover { 26 background:#555 27 } 28 .dot.active { 29 background:#00FF41; 30 width:28px; 31 border-radius:5px 32 } 33 .dot-label { 34 width:10px; 35 height:10px; 36 border-radius:50%; 37 border:1.5px solid #444; 38 background:transparent; 39 color:transparent; 40 font-size:0; 41 padding:0; 42 cursor:pointer; 43 transition:all .3s; 44 line-height:0 45 } 46 .dot-label:hover { 47 border-color:#666 48 } 49 .dot-label.active { 50 background:transparent; 51 border-color:#00FF41; 52 color:#00FF41; 53 width:auto; 54 height:auto; 55 padding:2px 8px; 56 border-radius:10px; 57 font-size:10px; 58 font-weight:600; 59 font-family:system-ui, 60 sans-serif; 61 line-height:1.4 62 }
untitled.js wrap JavaScript
Copy 1 document.querySelectorAll('.dots-wrap').forEach(wrap=>{ 2 wrap.querySelectorAll('.dot,.dot-label').forEach(dot=>{ 3 dot.addEventListener('click',()=>{ 4 wrap.querySelectorAll('.dot,.dot-label').forEach(d=>d.classList.remove('active')); 5 dot.classList.add('active'); 6 }); 7 }); 8 })
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 sections.
minimal-pagination HTML CSS Live
Copy 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>
Copy 1 .pagination.minimal { 2 display:flex; 3 align-items:center; 4 gap:16px; 5 padding:20px 24px; 6 font-family:system-ui, 7 sans-serif; 8 justify-content:center 9 } 10 .page-link { 11 color:#808080; 12 text-decoration:none; 13 font-size:13px; 14 font-weight:500; 15 transition:color .2s; 16 position:relative 17 } 18 .page-link:hover { 19 color:#00FF41 20 } 21 .page-link::after { 22 content:''; 23 position:absolute; 24 bottom:-2px; 25 left:0; 26 width:0; 27 height:1px; 28 background:#00FF41; 29 transition:width .2s 30 } 31 .page-link:hover::after { 32 width:100% 33 } 34 .page-separator { 35 color:#333; 36 font-size:12px 37 } 38 .page-current { 39 font-size:12px; 40 color:#666 41 }
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-pagination HTML CSS JS Live
Copy 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" 37 stroke="currentColor" stroke-width="2" stroke-linecap="round" 38 stroke-linejoin="round"> 39 <polyline points="6 9 12 15 18 9"/> 40 </svg> 41 </button> 42 </div> 43 </div>
Copy 1 .load-more-demo { 2 max-width:420px; 3 margin:0 auto; 4 padding:16px 24px; 5 font-family:system-ui, 6 sans-serif 7 } 8 .lm-items { 9 display:flex; 10 flex-direction:column; 11 gap:0 12 } 13 .lm-item { 14 display:flex; 15 align-items:center; 16 gap:12px; 17 padding:10px 12px; 18 border-bottom:1px solid #1A1A1A; 19 font-size:12px; 20 color:#A0A0A0; 21 transition:background .15s 22 } 23 .lm-item:hover { 24 background:rgba(255, 25 255, 26 255, 27 .02) 28 } 29 .lm-num { 30 width:20px; 31 height:20px; 32 border-radius:50%; 33 background:rgba(255, 34 255, 35 255, 36 .04); 37 color:#666; 38 font-size:10px; 39 font-weight:600; 40 display:flex; 41 align-items:center; 42 justify-content:center; 43 flex-shrink:0 44 } 45 .lm-text { 46 flex:1; 47 line-height:1.4 48 } 49 .lm-footer { 50 display:flex; 51 align-items:center; 52 justify-content:space-between; 53 padding:12px 12px 0; 54 margin-top:4px 55 } 56 .lm-info { 57 font-size:11px; 58 color:#555 59 } 60 .lm-btn { 61 display:inline-flex; 62 align-items:center; 63 gap:6px; 64 padding:8px 16px; 65 border-radius:8px; 66 border:1px solid #2A2A2A; 67 background:transparent; 68 color:#A0A0A0; 69 font-size:12px; 70 font-weight:500; 71 font-family:system-ui, 72 sans-serif; 73 cursor:pointer; 74 transition:all .2s 75 } 76 .lm-btn:hover { 77 border-color:#00FF41; 78 color:#00FF41; 79 background:rgba(0, 80 255, 81 65, 82 .05) 83 } 84 .lm-btn.loading .lm-btn-text { 85 display:none 86 } 87 .lm-btn.loading::after { 88 content:''; 89 width:14px; 90 height:14px; 91 border:2px solid rgba(0, 92 255, 93 65, 94 .2); 95 border-top-color:#00FF41; 96 border-radius:50%; 97 animation:spin .6s linear infinite 98 } 99 @keyframes spin { 100 to { 101 transform:rotate(360deg) 102 } 103 }
untitled.js wrap JavaScript
Copy 1 document.getElementById('load-more-btn').addEventListener('click',function(){ 2 this.classList.add('loading'); 3 setTimeout(()=>{ 4 this.classList.remove('loading'); 5 document.querySelector('.lm-info').textContent='Showing 6 of 47 tasks'; 6 const container=document.querySelector('.lm-items'); 7 ['Review pull request #312 for security audit', 8 'Update CI pipeline to Node 22 LTS', 9 'Migrate user sessions to Redis cluster' 10 ].forEach((text,i)=>{ 11 const item=document.createElement('div'); 12 item.className='lm-item'; 13 item.style.opacity='0'; 14 item.style.transform='translateY(8px)'; 15 item.innerHTML='<span class="lm-num">'+(i+4)+'</span><span class="lm-text">'+text+'</span>'; 16 container.appendChild(item); 17 requestAnimationFrame(()=>{ 18 item.style.transition='all .3s ease'; 19 item.style.opacity='1'; 20 item.style.transform='translateY(0)'; 21 }); 22 }); 23 },800); 24 })
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.
Copy 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" 5 stroke="currentColor" stroke-width="2" stroke-linecap="round" 6 stroke-linejoin="round"> 7 <polyline points="15 18 9 12 15 6"/> 8 </svg> 9 </button> 10 <button class="page-btn"> 11 1 12 </button> 13 <span class="page-ellipsis"> 14 ··· 15 </span> 16 <button class="page-btn"> 17 18 18 </button> 19 <button class="page-btn active" aria-current="page"> 20 19 21 </button> 22 <button class="page-btn"> 23 20 24 </button> 25 <span class="page-ellipsis"> 26 ··· 27 </span> 28 <button class="page-btn"> 29 52 30 </button> 31 <button class="page-btn" aria-label="Next"> 32 <svg width="14" height="14" viewBox="0 0 24 24" fill="none" 33 stroke="currentColor" stroke-width="2" stroke-linecap="round" 34 stroke-linejoin="round"> 35 <polyline points="9 18 15 12 9 6"/> 36 </svg> 37 </button> 38 </nav> 39 <div class="jump-input-wrap"> 40 <span class="jump-label"> 41 Go to 42 </span> 43 <input type="number" class="jump-input" min="1" max="52" value="19" /> 44 <span class="jump-total"> 45 of 52 46 </span> 47 </div> 48 </div>
Copy 1 .jump-demo { 2 display:flex; 3 align-items:center; 4 gap:20px; 5 padding:20px 24px; 6 font-family:system-ui, 7 sans-serif; 8 flex-wrap:wrap; 9 justify-content:center 10 } 11 .pagination { 12 display:flex; 13 align-items:center; 14 gap:4px; 15 margin:0 16 } 17 .page-btn { 18 display:inline-flex; 19 align-items:center; 20 justify-content:center; 21 min-width:36px; 22 height:36px; 23 padding:0 10px; 24 border-radius:8px; 25 border:1px solid #2A2A2A; 26 background:transparent; 27 color:#A0A0A0; 28 font-size:13px; 29 font-weight:500; 30 font-family:system-ui, 31 sans-serif; 32 cursor:pointer; 33 transition:all .2s 34 } 35 .page-btn:hover:not(.active) { 36 border-color:#3A3A3A; 37 color:#E0E0E0; 38 background:rgba(255, 39 255, 40 255, 41 .03) 42 } 43 .page-btn.active { 44 background:#00FF41; 45 color:#0A0A0A; 46 border-color:#00FF41; 47 font-weight:700 48 } 49 .page-btn svg { 50 flex-shrink:0 51 } 52 .page-ellipsis { 53 display:inline-flex; 54 align-items:center; 55 justify-content:center; 56 min-width:36px; 57 height:36px; 58 color:#555; 59 font-size:14px; 60 letter-spacing:2px; 61 user-select:none 62 } 63 .jump-input-wrap { 64 display:flex; 65 align-items:center; 66 gap:8px; 67 font-size:12px; 68 color:#808080 69 } 70 .jump-label { 71 color:#666 72 } 73 .jump-input { 74 width:48px; 75 height:32px; 76 border-radius:6px; 77 border:1px solid #2A2A2A; 78 background:#0A0A0A; 79 color:#E0E0E0; 80 font-size:13px; 81 font-family:system-ui, 82 sans-serif; 83 text-align:center; 84 outline:none; 85 padding:0 86 } 87 .jump-input:focus { 88 border-color:#00FF41; 89 box-shadow:0 0 0 2px rgba(0, 90 255, 91 65, 92 .1) 93 } 94 .jump-input::-webkit-inner-spin-button, 95 .jump-input::-webkit-outer-spin-button { 96 -webkit-appearance:none; 97 margin:0 98 } 99 .jump-total { 100 color:#555 101 }
preview
HTML Structure
Use a <nav> element witharia-label="Pagination" . Mark the active page with aria-current="page" and disable prev/next at boundaries with thedisabled attribute.
pagination-structure.html wrap HTML
Copy 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"> 8 3 9 </button> 10 <button class="page-btn">4</button> 11 <button class="page-btn">5</button> 12 <button class="page-btn" aria-label="Next"> 13 <svg><!-- chevron right --></svg> 14 </button> 15 </nav>
ℹ info
Always set aria-current="page" on the active page button and disabled on prev/next when at boundaries. This ensures screen readers communicate the user's position without visual cues alone.
✓ best practice
For datasets under 20 items, consider a "Load More" button or infinite scroll instead of traditional pagination. Numbered pages work best when users need to revisit specific positions in the data or when the total count is known and stable.
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 keyboard users, ensure Tab moves between page buttons and Enter activates them.