Feedback on a Pagination Pattern

Remy Sharp asked on the Mastodon about pagination as he found it in the W3C Design System:

<nav aria-label="pagination" class="l-cluster pagination">
	<ul class="pagination__list">
		<li><a href="path/to/page">Previous <span class="visuallyhidden">page</span></a></li>
		<li><a class="pagination__list__first" href="path/to/page"><span class="visuallyhidden">page</span> 1<span
						class="visuallyhidden"> (first page)</span></a></li>
		<li><a class="ellipsis">…</a></li>
		<li><a href="path/to/page"><span class="visuallyhidden">page</span> 6</a></li>
		<li><a href="path/to/page"><span class="visuallyhidden">page</span> 7</a></li>
		<li><a href="#" aria-label="page 8" aria-current="page">8</a></li>
		<li><a href="path/to/page"><span class="visuallyhidden">page</span> 9</a></li>
		<li><a href="path/to/page"><span class="visuallyhidden">page</span> 10</a></li>
		<li><a class="ellipsis">…</a></li>
		<li><a class="pagination__list__last" href="path/to/page"><span class="visuallyhidden">page</span> 20<span
						class="visuallyhidden"> (last page)</span></a></li>
		<li><a href="path/to/page">Next <span class="visuallyhidden">page</span></a></li>
	</ul>
</nav>

He was curious if difference between the visible page numbers (as only numbers) and the expression via screen readers (as “page #”) is ok.

Broadly, yeah, it’s fine. However, I am of the opinion it is unnecessary.

How the Code Works

The Overall Experience

Specific Examples

This is using only desktop screen readers and only the most popular ones at that. After all, free labor.

My Recommendation

  1. Remove all the visually-hidden text.
  2. Remove all the aria-labels.
  3. Use hidden text to name the landmark with aria-labelledby.

Maybe something like:

<nav aria-labelledby="Pagination">
	<h2 id="Pagination" class="visuallyhidden">Pagination</h2>
	<ul>
		<li><a href="path/to/page">Previous</a></li>
		[…]
		<li><a href="#" aria-current="page">8</a></li>
		[…]
	</ul>
</nav>

I am torn on whether the current page should even be a link.

Why

The region is named “pagination” and the aria-current tells screen reader users that at least one of those is a page. This is really the only context users need. Voice users can benefit from an accessible name that matches what is shown. Braille display users can benefit from far briefer link text, particularly if using a display with few cells. Overall screen reader users get a less verbose experience.

I would probably ignore WCAG Success Criterion 2.4.9: Link Purpose (Link Only) (Level AAA) unless your own testing with users shows adding “page” to each link helps. In which case, do not visually hide “page”.

Understand that the pattern is not a W3C recommendation or even suggestion. It is a pattern built by the W3C’s web site vendor. You are not obligated to follow it. I did file an issue so the team could make up its own collective mind: #634 Simplify pagination pattern.

I understand your use case may differ and you may disagree with my opinions. Good for you.

3 Comments

Reply

Thank you always for your wonderful posts! Wouldn’t using the hidden attribute make the element excluded from machine translation?

I feel it might be better to do something like the following:

Pagination
….

What do you think?

ryo_manba; . Permalink
In response to ryo_manba. Reply

ryo_manba, the comment form accepts limited HTML and no MarkDown. I think you were asking about adding the class.

Yes, nodes with hidden do not always auto-translate (only descendant nodes seem to in Chrome, while in Firefox they translate). I adjusted to use the class. My mistake; I was writing too fast last night. Mostly I was trying to prevent there being another heading in the DOM, but there are plenty of other ways to do that.

In response to Adrian Roselli. Reply

Ah, sorry, it seems the markup was broken.
I think it was a good decision to use the class. Thanks for the fix!

ryo_manba; . Permalink

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>