Pagination
Pagination is used to navigate from page to page in paginated content, with a control for navigating to the next or previous page.
Examples
Default
The Default Pagination component is used to break up large sets of data across multiple pages. It is commonly used to navigate through items returned from a search or filtering operation.
<nav role="navigation" aria-label="Pages" class="bux-pagination">
<ul class="bux-pagination__list">
<li class="bux-pagination__item">
<a
aria-label="Go to previous page"
class="bux-pagination__link bux-pagination__link--previous"
href="#"
rel="noopener"
></a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 1"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">1</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 2"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">2</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Current page, page 3"
aria-current
class="bux-pagination__link bux-pagination__link--current"
href="#"
rel="noopener"
>
<span
class="bux-pagination__link__text bux-pagination__link--current__text"
>
3
</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 4"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">4</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 5"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">5</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Go to next page"
class="bux-pagination__link bux-pagination__link--next"
href="#"
rel="noopener"
></a>
</li>
</ul>
</nav>
{#
Buckeye UX - version 1.5.0
Copyright (C) 2026 The Ohio State University
#}
{#
Pagination
Available Variables:
- current_page: Integer for the current page, starting at 1.
- previous_page: URL of the previous page.
- next_page: URL of the next page.
- zero_based_index: Optional. Boolean. Set to true if your system is using zero based indexing.
- total_pages: Integer value of the total number of pages, starting at 1.
- pages: Array containing the URLs of all pages.
- modifier: Optional. Sets the pagination variant: null, alt.
- truncate_start: Optional. Boolean. Set to true to truncate pagination at start.
- truncate_end: Optional. Boolean. Set to true to truncate pagination at end.
- show_last_page: Optional. Boolean. Set to true if you want to show the last page.
- truncate_pages: Optional. Array containing a list of pages to truncate.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 04-01-2026 12:11:29
#}
{% set base = 0 %}
{% if zero_based_index %}
{% set base = 1 %}
{% endif %}
<nav role="navigation" aria-label="Pages" class="bux-pagination{{ modifier ? ' bux-pagination--' ~ modifier : '' }}">
<ul class="bux-pagination__list">
{# Display previous link if we"re not on the first page. #}
{% if previous_page %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--previous',
link_url: previous_page,
attributes: {
'aria-label': 'Go to previous page'
}
} %}
</li>
{% endif %}
{# Display ellipsis if truncate_start. #}
{% if truncate_start == true %}
<li class="bux-pagination__item">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true" role="presentation">
</span>
</li>
{% endif %}
{% for key, page in pages %}
<li class="bux-pagination__item">
{% if current_page == key %}
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--current',
link_url: page,
link_text: key + base,
show_underline: false,
attributes: {
'aria-label': 'Current page, page ' ~ (key + base),
'aria-current': true
}
} %}
{% else %}
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link',
link_url: page,
link_text: key + base,
show_underline: false,
attributes: {
'aria-label': 'Page ' ~ (key + base)
}
} %}
{% endif %}
</li>
{% endfor %}
{# Display ellipsis if truncate_end. #}
{% if truncate_end == true %}
<li class="bux-pagination__item">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true" role="presentation">
</span>
</li>
{% if show_last_page == true %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link',
link_url: pages|last,
link_text: total_pages + base,
show_underline: false,
attributes: {
'aria-label': 'Page ' ~ (total_pages + base)
}
} %}
</li>
{% endif %}
{% endif %}
{# Display next link if we"re not on the last page. #}
{% if next_page %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--next',
link_url: next_page,
attributes: {
'aria-label': 'Go to next page'
}
} %}
</li>
{% endif %}
</ul>
</nav>
{# Default pagination to be used in a Drupal 9 theme. #}
{% if items %}
<nav role="navigation" aria-label="Pagination" class="bux-pagination{% if modifier %} bux-pagination--{{ modifier }}{% endif %}">
<ul class="bux-pagination__list">
{# Print previous item if we are not on the first page. #}
{% if items.previous %}
<li class="bux-pagination__item bux-pagination__item--previous">
<a class="bux-pagination__link bux-pagination__link--previous" href="{{ items.previous.href }}" aria-label="Go to previous page" rel="prev"{{ items.previous.attributes|without('href', 'title', 'rel') }}>
</a>
</li>
{% endif %}
{# Add an ellipsis if there are further previous pages. #}
{% if ellipses.previous %}
<li class="bux-pagination__item" role="presentation">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true"></span>
</li>
{% endif %}
{# Now generate the actual pager piece. #}
{% for key, item in items.pages %}
<li class="bux-pagination__item">
{% if current == key %}
<a class="bux-pagination__link bux-pagination__link--current" href="{{ item.href }}" aria-label="Current page, page {{ key }}" aria-current="true">
{{- key -}}
</a>
{% else %}
<a class="bux-pagination__link" href="{{ item.href }}" aria-label="Go to page {{ key }}">
{{- key -}}
</a>
{% endif %}
</li>
{% endfor %}
{# Add an ellipsis if there are further next pages. #}
{% if ellipses.next %}
<li class="bux-pagination__item" role="presentation">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true"></span>
</li>
{% endif %}
{# Print next item if we are not on the last page. #}
{% if items.next %}
<li class="bux-pagination__item bux-pagination__item--next">
<a class="bux-pagination__link bux-pagination__link--next" href="{{ items.next.href }}" aria-label="Go to next page" rel="next"{{ items.next.attributes|without('href', 'title', 'rel') }}>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
Alternate Pagination
When using pagination on a light background that isn't white, use this variant so there is proper contrast between the background and the pagination.
<nav
role="navigation"
aria-label="Pages"
class="bux-pagination bux-pagination--alt"
>
<ul class="bux-pagination__list">
<li class="bux-pagination__item">
<a
aria-label="Go to previous page"
class="bux-pagination__link bux-pagination__link--previous bux-pagination__link bux-pagination__link--previous--alt"
href="#"
rel="noopener"
></a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 1"
class="bux-pagination__link bux-pagination__link--alt"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">1</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 2"
class="bux-pagination__link bux-pagination__link--alt"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">2</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Current page, page 3"
aria-current
class="bux-pagination__link bux-pagination__link--current bux-pagination__link bux-pagination__link--current--alt"
href="#"
rel="noopener"
>
<span
class="bux-pagination__link__text bux-pagination__link--current__text"
>
3
</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 4"
class="bux-pagination__link bux-pagination__link--alt"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">4</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 5"
class="bux-pagination__link bux-pagination__link--alt"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">5</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Go to next page"
class="bux-pagination__link bux-pagination__link--next bux-pagination__link bux-pagination__link--next--alt"
href="#"
rel="noopener"
></a>
</li>
</ul>
</nav>
{#
Buckeye UX - version 1.5.0
Copyright (C) 2026 The Ohio State University
#}
{#
Pagination
Available Variables:
- current_page: Integer for the current page, starting at 1.
- previous_page: URL of the previous page.
- next_page: URL of the next page.
- zero_based_index: Optional. Boolean. Set to true if your system is using zero based indexing.
- total_pages: Integer value of the total number of pages, starting at 1.
- pages: Array containing the URLs of all pages.
- modifier: Optional. Sets the pagination variant: null, alt.
- truncate_start: Optional. Boolean. Set to true to truncate pagination at start.
- truncate_end: Optional. Boolean. Set to true to truncate pagination at end.
- show_last_page: Optional. Boolean. Set to true if you want to show the last page.
- truncate_pages: Optional. Array containing a list of pages to truncate.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 04-01-2026 12:11:29
#}
{% set base = 0 %}
{% if zero_based_index %}
{% set base = 1 %}
{% endif %}
<nav role="navigation" aria-label="Pages" class="bux-pagination{{ modifier ? ' bux-pagination--' ~ modifier : '' }}">
<ul class="bux-pagination__list">
{# Display previous link if we"re not on the first page. #}
{% if previous_page %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--previous',
link_url: previous_page,
attributes: {
'aria-label': 'Go to previous page'
}
} %}
</li>
{% endif %}
{# Display ellipsis if truncate_start. #}
{% if truncate_start == true %}
<li class="bux-pagination__item">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true" role="presentation">
</span>
</li>
{% endif %}
{% for key, page in pages %}
<li class="bux-pagination__item">
{% if current_page == key %}
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--current',
link_url: page,
link_text: key + base,
show_underline: false,
attributes: {
'aria-label': 'Current page, page ' ~ (key + base),
'aria-current': true
}
} %}
{% else %}
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link',
link_url: page,
link_text: key + base,
show_underline: false,
attributes: {
'aria-label': 'Page ' ~ (key + base)
}
} %}
{% endif %}
</li>
{% endfor %}
{# Display ellipsis if truncate_end. #}
{% if truncate_end == true %}
<li class="bux-pagination__item">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true" role="presentation">
</span>
</li>
{% if show_last_page == true %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link',
link_url: pages|last,
link_text: total_pages + base,
show_underline: false,
attributes: {
'aria-label': 'Page ' ~ (total_pages + base)
}
} %}
</li>
{% endif %}
{% endif %}
{# Display next link if we"re not on the last page. #}
{% if next_page %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--next',
link_url: next_page,
attributes: {
'aria-label': 'Go to next page'
}
} %}
</li>
{% endif %}
</ul>
</nav>
Truncated Pagination
Behavior of the pagination when there are more pages than can be displayed at one time.
<nav role="navigation" aria-label="Pages" class="bux-pagination">
<ul class="bux-pagination__list">
<li class="bux-pagination__item">
<a
aria-label="Go to previous page"
class="bux-pagination__link bux-pagination__link--previous"
href="#"
rel="noopener"
></a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 1"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">1</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 2"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">2</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 3"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">3</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Current page, page 4"
aria-current
class="bux-pagination__link bux-pagination__link--current"
href="#"
rel="noopener"
>
<span
class="bux-pagination__link__text bux-pagination__link--current__text"
>
4
</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 5"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">5</span>
</a>
</li>
<li class="bux-pagination__item">
<span
class="bux-pagination__link bux-pagination__link--truncated"
aria-hidden="true"
role="presentation"
></span>
</li>
<li class="bux-pagination__item">
<a
aria-label="Page 10"
class="bux-pagination__link"
href="#"
rel="noopener"
>
<span class="bux-pagination__link__text">10</span>
</a>
</li>
<li class="bux-pagination__item">
<a
aria-label="Go to next page"
class="bux-pagination__link bux-pagination__link--next"
href="#"
rel="noopener"
></a>
</li>
</ul>
</nav>
{#
Buckeye UX - version 1.5.0
Copyright (C) 2026 The Ohio State University
#}
{#
Pagination
Available Variables:
- current_page: Integer for the current page, starting at 1.
- previous_page: URL of the previous page.
- next_page: URL of the next page.
- zero_based_index: Optional. Boolean. Set to true if your system is using zero based indexing.
- total_pages: Integer value of the total number of pages, starting at 1.
- pages: Array containing the URLs of all pages.
- modifier: Optional. Sets the pagination variant: null, alt.
- truncate_start: Optional. Boolean. Set to true to truncate pagination at start.
- truncate_end: Optional. Boolean. Set to true to truncate pagination at end.
- show_last_page: Optional. Boolean. Set to true if you want to show the last page.
- truncate_pages: Optional. Array containing a list of pages to truncate.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 04-01-2026 12:11:29
#}
{% set base = 0 %}
{% if zero_based_index %}
{% set base = 1 %}
{% endif %}
<nav role="navigation" aria-label="Pages" class="bux-pagination{{ modifier ? ' bux-pagination--' ~ modifier : '' }}">
<ul class="bux-pagination__list">
{# Display previous link if we"re not on the first page. #}
{% if previous_page %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--previous',
link_url: previous_page,
attributes: {
'aria-label': 'Go to previous page'
}
} %}
</li>
{% endif %}
{# Display ellipsis if truncate_start. #}
{% if truncate_start == true %}
<li class="bux-pagination__item">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true" role="presentation">
</span>
</li>
{% endif %}
{% for key, page in pages %}
<li class="bux-pagination__item">
{% if current_page == key %}
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--current',
link_url: page,
link_text: key + base,
show_underline: false,
attributes: {
'aria-label': 'Current page, page ' ~ (key + base),
'aria-current': true
}
} %}
{% else %}
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link',
link_url: page,
link_text: key + base,
show_underline: false,
attributes: {
'aria-label': 'Page ' ~ (key + base)
}
} %}
{% endif %}
</li>
{% endfor %}
{# Display ellipsis if truncate_end. #}
{% if truncate_end == true %}
<li class="bux-pagination__item">
<span class="bux-pagination__link bux-pagination__link--truncated" aria-hidden="true" role="presentation">
</span>
</li>
{% if show_last_page == true %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link',
link_url: pages|last,
link_text: total_pages + base,
show_underline: false,
attributes: {
'aria-label': 'Page ' ~ (total_pages + base)
}
} %}
</li>
{% endif %}
{% endif %}
{# Display next link if we"re not on the last page. #}
{% if next_page %}
<li class="bux-pagination__item">
{% include '@bux/link/link.twig' with {
base_class: 'bux-pagination__link bux-pagination__link--next',
link_url: next_page,
attributes: {
'aria-label': 'Go to next page'
}
} %}
</li>
{% endif %}
</ul>
</nav>
Document Pagination
The Document Pagination component is used for page-by-page navigation through content that is meant to be viewed in sequential order. It is often used for content such as books, manuals, or courses.
<nav aria-label="Document pages" class="bux-doc-pagination">
<div class="bux-doc-pagination__item bux-doc-pagination__item--prev">
<a
rel="prev noopener"
class="bux-doc-pagination__link bux-doc-pagination__link--prev"
href="#"
>
<div class="bux-doc-pagination__label bux-doc-pagination__label--prev">
Page 3
</div>
</a>
</div>
<div class="bux-doc-pagination__item bux-doc-pagination__item--next">
<a
rel="next noopener"
class="bux-doc-pagination__link bux-doc-pagination__link--next"
href="#"
>
<div class="bux-doc-pagination__label bux-doc-pagination__label--next">
Page 5
</div>
</a>
</div>
</nav>
{#
Buckeye UX - version 1.5.0
Copyright (C) 2026 The Ohio State University
#}
{#
Doc Pagination
Available Variables:
- previous_page: URL for the previous page.
- next_page: URL for the next page.
This DocBlock is auto-generated and any changes could be overwritten.
Use the component's corresponding *.config.ts to make changes to this file.
Last Updated: 04-01-2026 14:17:49
#}
<nav aria-label="Document pages" class="bux-doc-pagination">
{% if previous_page %}
<div class="bux-doc-pagination__item bux-doc-pagination__item--prev">
{% embed '@bux/link/link.twig'
with {
base_class: 'bux-doc-pagination__link bux-doc-pagination__link--prev',
link_url: previous_page.url,
attributes: {
rel: 'prev'
}
}
%}
{% block content %}
<div class="bux-doc-pagination__label bux-doc-pagination__label--prev">
{{ previous_page.label }}
</div>
{% endblock content %}
{% endembed %}
</div>
{% endif %}
{% if next_page %}
<div class="bux-doc-pagination__item bux-doc-pagination__item--next">
{% embed '@bux/link/link.twig'
with {
base_class: 'bux-doc-pagination__link bux-doc-pagination__link--next',
link_url: next_page.url,
attributes: {
rel: 'next'
}
}
%}
{% block content %}
<div class="bux-doc-pagination__label bux-doc-pagination__label--next">
{{ next_page.label }}
</div>
{% endblock content %}
{% endembed %}
</div>
{% endif %}
</nav>
Usage
Dos
- Use on websites where users are looking for specific pieces of content, such as search results, articles related to a tag, or archives
- Pagination is good for page load since the content on the page is limited by what is shown for each page
Don’ts
- Don’t use when users are exploring content or browsing aimlessly for something interesting; consider infinite scrolling instead
- Infinite scrolling will continue to roll out relevant content in a way that is efficient, digestible, and interruption-free
- Don't use more than five pages in the page list. If the document or collection has more than five pages, use Truncated Pagination instead
Implementation Notes
Javascript
- The current page in the pagination list must have the
aria-currentrole set to 'page' - Pagination must be in a
navlandmark
Accessibility
- When using the Reverse variant, the background color must have a 4.5:1 contrast ratio with white (#FFFFFF)
- Pagination references