Pagination

Pagination splits a long list of results — trail listings, search results, blog posts — into numbered pages, and gives the user Previous/Next controls to move between them. Like breadcrumbs, it's a pure-CSS component: no JavaScript is bundled with it, because which page loads next is your application's job (a link, a query string, a page reload), not Bootstrap's. We'll build a "page 2 of 8" control for a TrailMap trail-listing page.

1. The Basic .pagination Markup

A pagination control is an unordered list with .pagination, where each page number is a .page-item wrapping a .page-link.

<nav aria-label="Page navigation">
  <ul class="pagination">
    <li class="page-item"><a class="page-link" href="#">1</a></li>
    <li class="page-item"><a class="page-link" href="#">2</a></li>
    <li class="page-item"><a class="page-link" href="#">3</a></li>
  </ul>
</nav>

2. Disabled and Active States

The current page gets .page-item.active (highlighted, and marked aria-current="page"); a control that can't be used right now — like "Previous" on page 1 — gets .page-item.disabled plus aria-disabled="true", since a plain <a> tag has no native disabled state of its own.

<ul class="pagination">
  <li class="page-item disabled">
    <a class="page-link" href="#" tabindex="-1" aria-disabled="true">Previous</a>
  </li>
  <li class="page-item active" aria-current="page">
    <a class="page-link" href="#">1</a>
  </li>
  <li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
Note: tabindex="-1" on the disabled link keeps keyboard users from tabbing into a control that does nothing.

3. Sizing: .pagination-lg / .pagination-sm

Add .pagination-lg to the <ul> for larger, easier-to-tap page links, or .pagination-sm for a more compact control. With no sizing class, you get the default size.

<!-- Large -->
<ul class="pagination pagination-lg">...</ul>

<!-- Small -->
<ul class="pagination pagination-sm">...</ul>

4. Alignment With Flex Utilities

.pagination is a flex container by default, so centering or right-aligning it is just a matter of adding a flex justify-content utility to the wrapping <nav> or <ul> itself — no special pagination-specific alignment class needed.

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

<!-- Right-aligned -->
<ul class="pagination justify-content-end">...</ul>

5. Worked Example — TrailMap "Page 2 of 8"

A centered pagination control for a trail-listing page currently on page 2 of 8, showing a windowed set of page numbers around the current page plus working Previous/Next links.

<nav aria-label="Trail listing pages">
  <ul class="pagination justify-content-center">
    <li class="page-item">
      <a class="page-link" href="?page=1">Previous</a>
    </li>
    <li class="page-item"><a class="page-link" href="?page=1">1</a></li>
    <li class="page-item active" aria-current="page">
      <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 disabled">
      <span class="page-link">…</span>
    </li>
    <li class="page-item"><a class="page-link" href="?page=8">8</a></li>
    <li class="page-item">
      <a class="page-link" href="?page=3">Next</a>
    </li>
  </ul>
</nav>

Page 2's <li> carries .active and aria-current="page"; the "…" gap is a non-interactive .page-item.disabled holding a plain <span> instead of a link, since it isn't a page you can jump to directly.

Next up: Progress Bars — visually showing completion or a rated value, which pairs nicely with a trail's difficulty rating.