Components

Bootstrap Pagination: Bootstrap 5 Guide with Examples

By the bootstrap.build team · 4 min read · Published

Bootstrap pagination is the row of page numbers under a list of blog posts, search results, products, or table rows. It is pure HTML and CSS: a list of links with Bootstrap’s styling, no JavaScript involved. This guide covers the markup, the current and disabled pages, previous and next arrows, sizes, alignment, long page ranges with ellipses, pagination that fits on phones, styling, generating the links with JavaScript, and how to make paginated pages work well for search engines. Everything is for Bootstrap 5.3.

Basic pagination

<nav aria-label="Blog pages">
  <ul class="pagination">
    <li class="page-item"><a class="page-link" href="/blog/page/1/">1</a></li>
    <li class="page-item active"><a class="page-link" href="/blog/page/2/" aria-current="page">2</a></li>
    <li class="page-item"><a class="page-link" href="/blog/page/3/">3</a></li>
  </ul>
</nav>
Part Job
<nav aria-label> Marks the pagination as navigation and names it for screen readers
.pagination The row
.page-item One page; active or disabled mark its state
.page-link The link itself

aria-current="page" tells screen readers which page is open; the active class only changes the look.

Previous and next

<nav aria-label="Search results pages">
  <ul class="pagination">
    <li class="page-item disabled">
      <span class="page-link">Previous</span>
    </li>
    <li class="page-item active"><a class="page-link" href="?page=1" aria-current="page">1</a></li>
    <li class="page-item"><a class="page-link" href="?page=2">2</a></li>
    <li class="page-item"><a class="page-link" href="?page=3">3</a></li>
    <li class="page-item"><a class="page-link" href="?page=2">Next</a></li>
  </ul>
</nav>

On the first page, “Previous” has nowhere to go, so it is disabled and a <span> instead of a link: a disabled link can still be reached by the Tab key. Use the same pattern for “Next” on the last page.

To use arrows instead of words, keep a text label for screen readers:

<li class="page-item">
  <a class="page-link" href="?page=2" aria-label="Next page"><span aria-hidden="true">&raquo;</span></a>
</li>

Sizes

<ul class="pagination pagination-lg">...</ul>
<ul class="pagination pagination-sm">...</ul>

Alignment

.pagination is a flex row, so the flex utilities position it:

<ul class="pagination justify-content-center">...</ul>
<ul class="pagination justify-content-end">...</ul>

Long page ranges

With many pages, show the first, the last, and a few around the current one, with an ellipsis for the gaps:

<nav aria-label="Product pages">
  <ul class="pagination justify-content-center">
    <li class="page-item"><a class="page-link" href="?page=6">Previous</a></li>
    <li class="page-item"><a class="page-link" href="?page=1">1</a></li>
    <li class="page-item disabled"><span class="page-link">&hellip;</span></li>
    <li class="page-item"><a class="page-link" href="?page=6">6</a></li>
    <li class="page-item active"><a class="page-link" href="?page=7" aria-current="page">7</a></li>
    <li class="page-item"><a class="page-link" href="?page=8">8</a></li>
    <li class="page-item disabled"><span class="page-link">&hellip;</span></li>
    <li class="page-item"><a class="page-link" href="?page=24">24</a></li>
    <li class="page-item"><a class="page-link" href="?page=8">Next</a></li>
  </ul>
</nav>

Pagination on phones

A long row of numbers overflows small screens. Hide the outer numbers below a breakpoint with the display utilities:

<li class="page-item d-none d-sm-block"><a class="page-link" href="?page=6">6</a></li>

On phones this leaves Previous, the current page, and Next. Another option is the small size plus flex-wrap, which lets the row wrap onto a second line. The breakpoint values are in the breakpoints guide.

A simple “Older and newer” pager

For a blog, two links are often enough:

<nav aria-label="Posts">
  <ul class="pagination justify-content-between">
    <li class="page-item"><a class="page-link" href="/blog/page/3/">&larr; Newer posts</a></li>
    <li class="page-item"><a class="page-link" href="/blog/page/5/">Older posts &rarr;</a></li>
  </ul>
</nav>

Style pagination

Pagination uses CSS variables, so you can restyle it without Sass:

.pagination {
  --bs-pagination-color: #2f55ff;
  --bs-pagination-active-bg: #2f55ff;
  --bs-pagination-active-border-color: #2f55ff;
  --bs-pagination-hover-bg: #eef2ff;
  --bs-pagination-border-radius: .75rem;
  --bs-pagination-focus-box-shadow: 0 0 0 .25rem rgba(47, 85, 255, .25);
}

For separate rounded buttons instead of a joined bar, add gap-2 to .pagination and round every link:

.pagination.gap-2 .page-link { border-radius: 50rem; }

The active color follows $primary, so changing the primary color restyles pagination with everything else. In Sass, $pagination-padding-x, $pagination-border-radius, and $pagination-active-bg set the defaults.

Generate pagination with JavaScript

For a list loaded in the browser, build the links from the current page and the page count:

function renderPagination(container, current, total, url = page => `?page=${page}`) {
  const pages = [...new Set([1, current - 1, current, current + 1, total])]
    .filter(p => p >= 1 && p <= total).sort((a, b) => a - b)

  const item = (label, page, state = '') => state === 'disabled'
    ? `<li class="page-item disabled"><span class="page-link">${label}</span></li>`
    : `<li class="page-item ${state}"><a class="page-link" href="${url(page)}"${state === 'active' ? ' aria-current="page"' : ''}>${label}</a></li>`

  let html = item('Previous', current - 1, current === 1 ? 'disabled' : '')
  pages.forEach((page, i) => {
    if (i > 0 && page - pages[i - 1] > 1) html += item('&hellip;', 0, 'disabled')
    html += item(page, page, page === current ? 'active' : '')
  })
  html += item('Next', current + 1, current === total ? 'disabled' : '')
  container.innerHTML = html
}

renderPagination(document.querySelector('.pagination'), 7, 24)

Pagination and SEO

  • Use real links. Each page needs its own URL in an <a href>. Buttons that load more items with JavaScript and no URL hide those items from search engines.
  • Give each page its own canonical URL. Page 2 should point its canonical tag at page 2, not at page 1, or search engines may ignore the products and posts listed there.
  • Don’t rely on rel="prev" and rel="next". Google no longer uses them, though they do no harm.

FAQ

How do I make pagination in Bootstrap 5?

Wrap a <ul class="pagination"> in a <nav aria-label="...">, and add a <li class="page-item"> with an <a class="page-link"> for each page. Mark the current page with active on the item and aria-current="page" on the link.

How do I center pagination in Bootstrap?

Add justify-content-center to the .pagination element. Use justify-content-end to align it to the right.

How do I change the color of Bootstrap pagination?

Set the --bs-pagination-active-bg, --bs-pagination-active-border-color, and --bs-pagination-color CSS variables on .pagination. The active color comes from $primary by default.

Add disabled to the .page-item and replace the link with <span class="page-link">. A span can’t be clicked or reached with the Tab key, unlike a link that is only styled as disabled.

How do I make Bootstrap pagination responsive?

Hide the outer page numbers on small screens with d-none d-sm-block on their .page-item, leaving Previous, the current page, and Next. Or use pagination-sm with flex-wrap so the row wraps.

Try it in the builder

Make these changes visually with a live preview, then export clean Bootstrap Sass or CSS.

Open the Builder