Make WordPress Core

Opened 3 years ago

Closed 2 weeks ago

Last modified 2 weeks ago

#54260 closed enhancement (fixed)

Add accessible labels to pagination links

Reported by: michaelbourne's profile michaelbourne Owned by: joedolson's profile joedolson
Milestone: 6.7 Priority: normal
Severity: normal Version:
Component: General Keywords: has-patch commit
Focuses: accessibility Cc:

Description

The default behavior of paginate_links is to output link text with no context around the page numbers that the text represents.

WP Ref: https://developer.wordpress.org/reference/functions/paginate_links/

This is a sample of the default output:

<div class="nav-links">
  <span aria-current="page" class="page-numbers current">1</span>
  <a class="page-numbers" href="">2</a>
  <span class="page-numbers dots">…</span>
  <a class="page-numbers" href="">13</a>
  <a class="next page-numbers" href="">Next</a></div>

I believe the more accessible output would be this:

<div class="nav-links">
  <span aria-current="page" class="page-numbers current">1</span>
  <a class="page-numbers" href="" aria-label="Page 2">2</a>
  <span class="page-numbers dots">…</span>
  <a class="page-numbers" href="" aria-label="Page 13">13</a>
  <a class="next page-numbers" href="" aria-label="Next Page">Next</a></div>

This falls short of what most of us would call an acceptable level of readability for users with assistive technologies. A few small code changes could alleviate this, I believe.

W3 Ref: https://www.w3.org/WAI/WCAG21/Understanding/headings-and-labels#dfn-label

To go along with this, a small change to get_the_posts_pagination should be used to supply the translatable string for this label.

WP Ref: https://developer.wordpress.org/reference/functions/get_the_posts_pagination/

        $args = wp_parse_args(
            $args,
            array(
                'mid_size'           => 1,
                'prev_text'          => _x( 'Previous', 'previous set of posts' ),
                'next_text'          => _x( 'Next', 'next set of posts' ),
                'screen_reader_text' => __( 'Posts navigation' ),
                'aria_label'         => __( 'Posts' ),
                'links_aria_label'   => __( 'Page' ),
                'class'              => 'pagination',
            )
        );

Change History (24)

This ticket was mentioned in PR #1755 on WordPress/wordpress-develop by michaelbourne.


3 years ago
#1

  • Keywords has-patch added

Create a new default $arg in paginate_links and use aria-label to provide context to page links for better accessibility.

Trac ticket: https://core.trac.wordpress.org/ticket/54260#ticket

#2 @sabernhardt
3 years ago

Hi, and thanks for the report!

In ticket:24709, the before_page_number and after_page_number arguments were created so themes could add (non-visual) text to each of the page links.

The Twenty Twenty-One example has visible text.

If ARIA labels are included automatically, they should not override the context provided in these two arguments. (It might be worth using the label attributes as a fallback.)

Last edited 17 months ago by sabernhardt (previous) (diff)

#3 @michaelbourne
3 years ago

  • Resolution set to invalid
  • Status changed from new to closed

Hi @sabernhardt

I completely overlooked the fact I could use HTML in those args. Screen reader text is always better than an aria label if it can be used. I guess that renders this trac ticket (and the connected PR) moot!

Appreciate the second set of eyes, sometimes it's easy to drown in the codex :)

This ticket was mentioned in Slack in #accessibility by sabernhardt. View the logs.


3 years ago

#5 @sabernhardt
3 years ago

  • Keywords needs-patch added; has-patch removed
  • Milestone changed from Awaiting Review to Future Release
  • Resolution invalid deleted
  • Status changed from closed to reopened
  • Version 5.8.1 deleted

Reopening to consider the possibility of adding an aria-label or something else if the theme does not include either the before_page_number or after_page_number argument

#6 @afercia
2 years ago

Worth reminding that providing an accessible name (via the aria-label) that is different and, in a way, unexpected compared to the visible text does impact speech recognition users. For example:

  • As a sighted speech recognition user, I see a link with text 2.
  • Based on that, I'd try to issue a voice command like Click 2.
  • The command would likely fail because the link accessible name (the name the speech recognition software perceives) would be Page 2.

In general, hidden labels/text (whether it's an aria-label or visually hidden text) may help blind screen reader users but they may be misleading or even an actual barrier for sighted users. It's always best to show visible text. If more context is needed, we should just add visible text.

Reference:
Success Criterion 2.5.3 Label in Name
https://www.w3.org/TR/WCAG21/#label-in-name

#7 @xyulex
18 months ago

I would like to get my hand on it!

This ticket was mentioned in PR #4429 on WordPress/wordpress-develop by @xyulex.


18 months ago
#8

  • Keywords has-patch added; needs-patch removed

Created aria-labels in paginate_links function.

This ticket was mentioned in PR #4429 on WordPress/wordpress-develop by @xyulex.


18 months ago
#9

Created aria-labels in paginate_links function.

#10 @sabernhardt
17 months ago

Instead of adding text to individual links (whether visible, screen reader only, or an aria-label), could the default aria-label for the nav container give more context? Right now, the label for the posts navigation is simply "Posts" but something like "Pages of posts" might help.

#11 @webmandesign
17 months ago

I think adding a filter for paginate_links() $args would help in this case. See #53859

Especially nowadays when building a block theme there is no way for me to change the HTML output of the Pagination block other than tweaking its HTML output (via render_block filter). This is not optimal and filtering the $args would provide more flexibility I think.

(I am building accessibility ready themes, so I would like to improve the HTML output of pagination too.)

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


3 months ago

#13 @joedolson
3 months ago

  • Milestone changed from Future Release to 6.7
  • Owner set to joedolson
  • Status changed from reopened to accepted

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


3 months ago

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


2 months ago

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


3 weeks ago

#17 @joedolson
3 weeks ago

On discussion, we're leaning towards changing the aria-label on the nav element to "Posts pagination" to provide the context here. The options for changing the link text themselves are already sufficient, so it doesn't make sense to add additional options there.

Adding a filter to allow extenders to modify these arguments does make sense to me, though - it would be nice to be able to change how a theme presents these links without needing to extend a child of every template using it.

You can already do that using the paginate_links_output filter, but it's labor intensive, since that requires you to either parse the HTML or rebuild it; filtering the arguments is much better for just tweaking how it works.

This ticket was mentioned in PR #7448 on WordPress/wordpress-develop by @tirth03.


2 weeks ago
#18

I have updated get_the_posts_pagination() function to get the post type name and use it in the aria_label for better accessibility text as described in ticket.

Before

https://github.com/user-attachments/assets/ebe97048-571d-425a-bf2f-3505c789af43

After

  1. Post

https://github.com/user-attachments/assets/d96f2943-3bca-4e16-85be-38c56ab95ef0

  1. Custom Post Type

https://github.com/user-attachments/assets/f3cbb4ba-9dc9-4d22-a1e9-334aa6341fe0

Trac ticket: https://core.trac.wordpress.org/ticket/54260

@joedolson commented on PR #7448:


2 weeks ago
#19

In addition, I changed the default screen_reader_text parameter to '%s pagination'. This makes the two strings match, which would otherwise be confusing.

This doesn't result in any string churn, since the Posts Navigation text will still be the default passed in non-paginated patterns.

#20 @joedolson
2 weeks ago

The main change in the updated PR is that pagination patterns use 'Posts pagination' where navigation patterns use just 'Posts'. The nav element will be read by screen readers as "posts navigation" if it's a prev/next navigation pattern; and as "posts pagination navigation" if it's pagination. This helps to differentiate the two types of navigation and provides meaningful context for the numbered links inside that region.

We do need to remove the change to use get_queried_object()->labels->name, however. As nice as it would be to use the post name, I had failed to take into account that using post names in generic strings creates a translation problem, because different post type names may have different genders in various languages, and translations can't dynamically account for that.

@joedolson commented on PR #7448:


2 weeks ago
#21

Removed the Posts string, translator comments, and reference to get_queried_object. That's my fault; I lead people down an invalid path, because we can't actually do that, as nice as it would be.

#22 @joedolson
2 weeks ago

  • Keywords commit added

#23 @joedolson
2 weeks ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 59113:

Accessibility: Clarify aria-label in pagination links.

Change posts and comments pagination nav regions to have an aria-label of "Posts pagination" and "Comments pagination", respectively. This provides improved context for the numeric links contained within these regions and differentiates between posts navigation regions and posts pagination regions.

Props michaelbourne, sabernhardt, afercia, xyulex, webmandesign, tirth03, joedolson.
Fixes #54260.

@joedolson commented on PR #7448:


2 weeks ago
#24

In r59113

Note: See TracTickets for help on using tickets.