CSS-Only

Pagination

Page navigation component with semantic markup, responsive behavior, and accessibility built-in. Works by default, enhances with data attributes.

Example

<nav aria-label="Pagination">
  <ul class="omni-pagination">
    <li class="omni-page" data-control="prev">
      <a href="?page=1" class="omni-page-link" aria-label="Previous page">‹</a>
    </li>
    <li class="omni-page">
      <a href="?page=1" class="omni-page-link">1</a>
    </li>
    <li class="omni-page">
      <a href="?page=2" class="omni-page-link" aria-current="page">2</a>
    </li>
    <li class="omni-page">
      <a href="?page=3" class="omni-page-link">3</a>
    </li>
    <li class="omni-page" data-control="next">
      <a href="?page=3" class="omni-page-link" aria-label="Next page">›</a>
    </li>
  </ul>
</nav>

Variants

Alignment

Use data-align to position the pagination:

Start (default)

Center

End

<ul class="omni-pagination" data-align="center">
  <!-- ... -->
</ul>

Minimal Style

Use data-style="minimal" for connected buttons:

<ul class="omni-pagination" data-style="minimal">
  <!-- ... -->
</ul>

With Ellipsis

Use .omni-page-ellipsis for long page ranges:

<li class="omni-page">
  <span class="omni-page-ellipsis" aria-hidden="true"></span>
</li>

With Icons

Use SVG icons for previous/next controls:

<li class="omni-page" data-control="prev">
  <a href="?page=1" class="omni-page-link" aria-label="Previous page">
    <svg>...</svg>
  </a>
</li>

Responsive

Use data-responsive="true" to hide page numbers on mobile (resize your browser to see):

<ul class="omni-pagination" data-responsive="true">
  <!-- On mobile, only controls and current page visible -->
</ul>

Current Page as Span

Use a <span> for the current page when it's not a link:

<li class="omni-page">
  <span class="omni-page-link" aria-current="page">2</span>
</li>

API Reference

Container Attributes

Attribute Values Default Description
data-align start, center, end start Horizontal alignment of pagination
data-style default, minimal default Visual style (separated vs connected buttons)
data-responsive true Hide page numbers on mobile (≤640px)

Classes

Class Element Description
.omni-pagination ul Pagination container (must be in <nav>)
.omni-page li Individual page item
.omni-page-link a, span Page link or current page indicator
.omni-page-ellipsis span Ellipsis indicator for long ranges

Required Attributes

Attribute Element Purpose
aria-label="Pagination" nav Identifies navigation landmark for screen readers
aria-current="page" .omni-page-link Indicates the current page to assistive technology
aria-label="Previous page" Previous control link Provides context for icon-only controls
aria-label="Next page" Next control link Provides context for icon-only controls
aria-hidden="true" .omni-page-ellipsis Hides decorative ellipsis from screen readers

Accessibility

  • Must be wrapped in <nav> with aria-label="Pagination" to identify the navigation landmark
  • Current page must use aria-current="page" to announce current location to screen readers
  • Previous/Next controls must use aria-label when using icons or symbols
  • Full keyboard navigation support (Tab, Enter, Space for links)
  • Focus visible indicators for all interactive elements
  • Ellipsis uses aria-hidden="true" as it's purely decorative
  • Current page can be a <span> (non-interactive) or <a> (interactive) element
  • Respects prefers-reduced-motion for transitions
  • Responsive mode maintains controls and current page on mobile for context

Example Markup Pattern

<nav aria-label="Pagination">
  <ul class="omni-pagination">
    <li class="omni-page" data-control="prev">
      <a href="?page=1" class="omni-page-link" aria-label="Previous page">
        <svg>...</svg>
      </a>
    </li>
    <li class="omni-page">
      <a href="?page=1" class="omni-page-link">1</a>
    </li>
    <li class="omni-page">
      <span class="omni-page-link" aria-current="page">2</span>
    </li>
    <li class="omni-page">
      <a href="?page=3" class="omni-page-link">3</a>
    </li>
    <li class="omni-page">
      <span class="omni-page-ellipsis" aria-hidden="true"></span>
    </li>
    <li class="omni-page">
      <a href="?page=10" class="omni-page-link">10</a>
    </li>
    <li class="omni-page" data-control="next">
      <a href="?page=3" class="omni-page-link" aria-label="Next page">
        <svg>...</svg>
      </a>
    </li>
  </ul>
</nav>