Pagination
When there is a lot of information to display on a page, the information can be divided into multiple pages and pagination links are provided so that users can navigate and access the information.
Similarly, in the case of multipage forms, pagination links help users to navigate between different sections of the form.
NOTE:
- New to accessibility or uncertain of requirements, it will be helpful to review all sections below.
- Already familiar with requirements, skip to the “Working Example” section for sample HTML, CSS and JavaScript (when needed), along with a working demo.
- Pagination links SHOULD be wrapped within a
<nav>
element -
Alternatively,
<div>
element withrole="navigation"
CAN be used to contain the pagination links. -
An
aria-label="Pagination"
SHOULD be specified on the<nav>
element or<div>
element withrole="navigation"
to provide an accessible name. -
Appropriate list mark-up such as
<ul>
and<li>
SHOULD be specified for the pagination links. For more information on making list accessible, see List component. - Unique and descriptive link text such as “Page 1”, “Page 2”, “Page 3”, “Previous Page”, “Next Page”, and so on SHOULD be specified for the pagination links. For more information to make links accessible, see Links component.
-
The current page link SHOULD contain
aria-current="page"
attribute to indicate its current state.
Note: An alternate way to convey the current state CAN be by specifying “current” keyword after the accessible name of the link. - Color along with additional visual cues such as bold text, underline and so on SHOULD be used to indicate the current page link. For more information on meeting color accessibility, refer to Color and Color Alone components.
-
In case where information is dynamically updating as per the selection of any pagination link,
- A hidden off-screen instruction SHOULD be given conveying this information to screen reader users.
- Focus SHOULD NOT update to the newly added content as this will forcefully shift users focus.
-
A feedback message CAN be announced to indicate the content has been
loaded/updated. For more information on how to handle dynamic updates, refer to
Dynamic Update,
Notifications and Alerts
components.
For example,<nav aria-label="pagination"> <ul> <li> <a href="#">Previous <span class="visuallyhidden">page</span></a> </li> <li> <a href="#"><span class="visuallyhidden">page</span> 1</a> </li> ... </ul> </nav>
Well-defined pagination links majorly benefit the below users.
- People with cognitive disabilities
- People with visual disabilities
- People using speech input
- People using keyboard only
- People with limited dexterity
<div class="content">
<div class="cards page active">
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide1">Learning Catalytics</a></h2>
<img src="../common-images/student-with-raised-hand-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Hear from every student when it matters most as they respond
using their own smartphones, tablets or laptops
</p>
<a href="#" aria-describedby="cardTitleSlide1">Explore Learning Catalytics</a>
</article>
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide2">StatCrunch</a></h2>
<img src="../common-images/educator-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Put the power of data in students' hands as they analyze
data sets easily from their text and exercises
</p>
<a href="#" aria-describedby="cardTitleSlide2">Explore StatCrunch</a>
</article>
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide3">MediaShare</a></h2>
<img src="../common-images/student-working-at-computer-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Bring course concepts to life and engage students with
media-rich activities, created with Pearson or your own content
</p>
<a href="#" aria-describedby="cardTitleSlide3">Explore MediaShare</a>
</article>
</div>
<div class="cards page">
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide4">StatCrunch</a></h2>
<img src="../common-images/educator-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Put the power of data in students' hands as they analyze
data sets easily from their text and exercises
</p>
<a href="#" aria-describedby="cardTitleSlide4">Explore StatCrunch</a>
</article>
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide5">MediaShare</a></h2>
<img src="../common-images/student-working-at-computer-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Bring course concepts to life and engage students with
media-rich activities, created with Pearson or your own content
</p>
<a href="#" aria-describedby="cardTitleSlide5">Explore MediaShare</a>
</article>
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide6">Learning Catalytics</a></h2>
<img src="../common-images/student-with-raised-hand-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Hear from every student when it matters most as they respond
using their own smartphones, tablets or laptops
</p>
<a href="#" aria-labelledby="cardTitleSlide6">Explore Learning Catalytics</a>
</article>
</div>
<div class="cards page">
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide7">MediaShare</a></h2>
<img src="../common-images/student-working-at-computer-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Bring course concepts to life and engage students with
media-rich activities, created with Pearson or your own content
</p>
<a href="#" aria-describedby="cardTitleSlide7">Explore MediaShare</a>
</article>
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide8">Learning Catalytics</a></h2>
<img src="../common-images/student-with-raised-hand-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Hear from every student when it matters most as they respond
using their own smartphones, tablets or laptops
</p>
<a href="#" aria-labelledby="cardTitleSlide8">Explore Learning Catalytics</a>
</article>
<article class="card reorder">
<h2><a href="#" id="cardTitleSlide9">StatCrunch</a></h2>
<img src="../common-images/educator-260x130.jpg" alt="" loading="lazy" width="260" height="130">
<p>
Put the power of data in students' hands as they analyze
data sets easily from their text and exercises
</p>
<a href="#" aria-describedby="cardTitleSlide9">Explore StatCrunch</a>
</article>
</div>
</div>
<nav aria-label="Pagination">
<div class="sr-only">
Activating any of the pagination links will update the content above.
</div>
<div class="pagination-container">
<a href="javascript:void(0)" aria-label="Previous Page" id="prevButton" class="c-blogList__pagination-prev" aria-disabled="true"><span aria-hidden="true"><</span></a>
<ul class="pagination" id="pagination">
<li class="page-item">
<a class="c-blogList__pagination-number selected" href="javascript:void(0)" data-page-number="1" aria-current="page"><span class="sr-only">Page </span>1</a>
</li>
<li class="page-item">
<a class="c-blogList__pagination-number" href="javascript:void(0)" data-page-number="2"><span class="sr-only">Page </span>2</a>
</li>
<li class="page-item">
<a class="c-blogList__pagination-number" href="javascript:void(0)" data-page-number="3"><span class="sr-only">Page </span>3</a>
</li>
</ul>
<a href="javascript:void(0)" aria-label="Next Page" class="c-blogList__pagination-next" id="nextButton" aria-disabled="false"><span aria-hidden="true">></span></a>
</div>
</nav>
body {
font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto,
Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
line-height: 1.4;
color: #333;
background: #efefef;
margin: 0 auto;
padding: 1em;
}
h2 {
font-size: 1.4rem;
margin-top: 0.5em;
margin-bottom: 0.2em;
line-height: 1;
}
.cards {
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
}
.cards > * {
flex: 0 1 25em;
}
.card {
margin: 0.75em;
padding: 0.75em;
border-radius: 3px;
border: 2px #ccc solid;
border-radius: 0.6em;
background-color: white;
position: relative;
}
img {
width: 100%;
height: auto;
}
.reorder {
display: flex;
flex-direction: column;
}
.reorder img {
max-width: 100%;
order: -1;
}
.card > * a,
.card > .cta {
display: block;
}
.card h2 > a {
text-decoration: none;
}
article:hover {
box-shadow: 0 0 0 0 0.25rem;
}
h1 {
text-align: center;
}
.pagination-container {
display: flex;
align-items: center;
}
.pagination {
display: flex;
list-style: none;
padding: 0;
}
.pagination li {
margin: 5px;
cursor: pointer;
}
.pagination li.active {
font-weight: bold;
}
.page {
display: none;
}
.page.active {
display: flex;
}
nav {
display: flex;
flex-direction: row;
justify-content: center;
}
.c-blogList__pagination-prev,
.c-blogList__pagination-next,
.c-blogList__pagination-number {
font-size: 16px;
font-weight: 400;
line-height: 36px;
color: rgb(21, 21, 21);
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
aspect-ratio: 1;
position: relative;
z-index: 1;
padding: 0;
text-decoration: none;
background-color: transparent;
border: medium none;
cursor: pointer;
}
.selected.c-blogList__pagination-number {
font-size: 16px;
font-weight: 645;
line-height: 36px;
color: rgb(254, 254, 254);
text-align: center;
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
aspect-ratio: 1;
position: relative;
z-index: 1;
padding: 0;
pointer-events: none;
}
.selected.c-blogList__pagination-number::before {
background-color: #151515;
transform: none;
transition: none;
border-radius: 50%;
width: 36px;
height: 36px;
border: 0.125em solid transparent;
display: block;
content: "";
flex: 0 0 auto;
position: absolute;
z-index: -1;
top: auto;
right: auto;
bottom: auto;
left: auto;
}
.c-blogList__pagination-prev[aria-disabled=true],
.c-blogList__pagination-next[aria-disabled=true] {
cursor: default;
pointer-events: none;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
let pagination = document.getElementById("pagination");
let contentPages = document.querySelectorAll(".page");
let pageItems = document.querySelectorAll(".page-item a");
let prevButton = document.getElementById("prevButton");
let nextButton = document.getElementById("nextButton");
let currentPage = 0;
pagination.addEventListener("click", (event) => {
if (event.target.tagName === "A") {
let pageNumber = parseInt(event.target.getAttribute("data-page-number"), 10);
setActivePage(pageNumber - 1);
}
});
prevButton.addEventListener("click", () => {
if (currentPage > 0) {
setActivePage(currentPage - 1);
}
});
nextButton.addEventListener("click", () => {
if (currentPage < contentPages.length - 1) {
setActivePage(currentPage + 1);
}
});
function setActivePage(pageNumber) {
contentPages[currentPage].classList.remove("active");
pageItems[currentPage].classList.remove("selected");
pageItems[currentPage].setAttribute("aria-current", "false");
currentPage = pageNumber;
contentPages[currentPage].classList.add("active");
pageItems[currentPage].classList.add("selected");
pageItems[currentPage].setAttribute("aria-current", "page");
prevButton.disabled = currentPage === 0;
nextButton.disabled = currentPage === contentPages.length - 1;
if (currentPage === 0) {
prevButton.setAttribute("aria-disabled", "true");
} else {
prevButton.setAttribute("aria-disabled", "false");
}
if (currentPage === contentPages.length - 1) {
nextButton.setAttribute("aria-disabled", "true");
} else {
nextButton.setAttribute("aria-disabled", "false");
}
}
Due to the nature of this demonstration, it is best
viewed full screen
.