Make WordPress Core

Opened 5 months ago

Last modified 20 hours ago

#47123 assigned defect (bug)

The post(s) navigation landmark needs to be labelled

Reported by: afercia Owned by: williampatton
Milestone: 5.3 Priority: normal
Severity: normal Version:
Component: Bundled Theme Keywords: has-screenshots has-patch
Focuses: accessibility, template Cc:

Description (last modified by afercia)

Basically all the Bundled Themes use previous / next navigation in the single post and pagination links in the posts / comments archives.

The markup output is responsibility of the core function _navigation_markup, which prints out an unlabelled <nav> element:

<nav class="navigation post-navigation" role="navigation">

Why it is a problem

This <nav> element defines an ARIA landmark by default: landmarks help assistive technology users to perceive the page main sections and jump through them. However, when a landmark is used more than once in a page, it needs to be distinguished from the other ones to let users understand what the landmark is about.

For example, in Twenty Nineteen there may be up to 4 navigation landmark, plus the WordPress toolbar when logged in. These landmarks are well labelled except the post / posts navigation one. See screenshot from the VoiceOver landmarks list:


Users won't have a clue what that landmark region is about.

Suggested solution

To properly label this landmark, there's the need to add an aria-label attribute with a meaningful text. The following W3C examples clarify further:

W3C landmarks example with detailed instructions:

If a specific landmark role is used more than once on a web page, it should have a unique label.
Avoid using the landmark role as part of the label. For example, a navigation landmark with a label "Site Navigation" will be announced by a screen reader as "Site Navigation Navigation". The label should simply be "Site".

W3C example using equivalent HTML5 sectioning elements
e.g. main, nav, aside ... define ARIA landmarks by default


_navigation_markup is used by other functions with different context: single views, archies, post, comments...:

  • the_post_navigation() / get_the_post_navigatio()n
  • the_posts_navigation() / get_the_posts_navigation()
  • the_posts_pagination() / get_the_posts_pagination()
  • the_comments_navigation() / get_the_comments_navigation()
  • the_comments_pagination() / get_the_comments_pagination()

Therefore, the aria-label value should be meaningful for all these different cases.

Note: in some cases, the <nav> element contains also a visually hidden heading, e.g.:
<h2 class="screen-reader-text">Post navigation</h2>

In these cases it's worth evaluating to use aria-labelledby on the <nav> element, targeting the hidden heading.

I'd like to hear the accessibility team thoughts on this. From a technical perspective, this would be a bit challenging, as _navigation_markup is used in different scenarios.

Note: filing under the "Bundled Theme" component even if this is output by core, as it impacts themes templating. Please do feel free to assign to a more appropriate component if desired.

Attachments (2)

47123.diff (8.7 KB) - added by sabernhardt 4 weeks ago.
47123.2.diff (11.3 KB) - added by afercia 41 hours ago.

Download all attachments as: .zip

Change History (15)

#1 @afercia
3 months ago

  • Description modified (diff)

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

3 months ago

#3 @SergeyBiryukov
3 months ago

To properly label this landmark, there's the need to add an aria-label attribute with a meaningful text.

Could the existing post type / taxonomy label items_list_navigation be used here? The defaults are:

  • Post types, non-hierarchical: Posts list navigation
  • Post types, hierarchical: Pages list navigation
  • Taxonomies, non-hierarchical: Tags list navigation
  • Taxonomies, hierarchical: Categories list navigation

#4 @afercia
3 months ago

@SergeyBiryukov interesting, thanks! I'm afraid these existing labels wouldn't be appropriate though because:

  • we need a label also for comments
  • the word list suggests there's a list: that's true for the posts tables (where these labels are currently used) but in this navigation there's no list, there's just a navigation
  • more importantly: the labels should not contain the word navigation: that's already automatically announced by screen readers because of the <nav> element

For example, in the case of comments, the ideal markup would be:

<nav class="navigation comment-navigation" role="navigation" aria-label="Comments">
	<h2 class="screen-reader-text">Comments navigation</h2>
	<div class="nav-links"> ... </div>

Maybe we could try to use the object plural name, not sure if that's reliable enough to have a meaningful name for the navigation.

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

3 months ago

#6 @williampatton
3 months ago

  • Owner set to williampatton
  • Status changed from new to assigned

#7 @afercia
3 months ago

  • Milestone changed from Awaiting Review to 5.3

Discussed during today's accessibility bug scrub. Moving to 5.3 consideration.

4 weeks ago

#8 @sabernhardt
4 weeks ago

Here is a patch that introduces the "aria_label" argument to each of the hooks that involve the _navigation_markup function.

The default ARIA label is either "Posts" or "Comments" for those navigation elements in their default usage. However, if the screen_reader_text argument is specified, then the default label may not apply. So the screen_reader_text becomes the ARIA label, even if it might be redundant with the element name. Similarly, customizations to the template using the navigation_markup_template filter have a screen_reader_text fallback as well.

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

2 weeks ago

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

4 days ago

#11 @sabernhardt
4 days ago

@afercia Thanks for calling attention to two scenarios I failed to test/verify earlier. It seems the patch from 3 weeks ago passed both tests today.

A posts taxonomy archive page has almost the same markup for its older/newer posts links as a single post has for its previous/next navigation links (at least in Twenty Nineteen). That is, the special nav class is "pagination" on the archive page instead of "post-navigation":
<nav class="navigation post-navigation" role="navigation" aria-label="Posts"><h2 class="screen-reader-text">Post navigation</h2><div class="nav-links"> ... </div></nav>

And I verified that a custom post type (for example, Projects) can use the_post_navigation in the theme templates for single (project) pages. Custom arguments can redefine previous/next links, screen reader text, and/or aria-label to match the post type. A theme taxonomy template also can be adjusted for custom taxonomy archives.

41 hours ago

#12 @afercia
41 hours ago

  • Keywords has-patch added

47123.2.diff applies a few minor coding standards.

@sabernhardt when you have a chance I'd appreciate your help checking I haven't messed up anything :) Thanks!

  • all the functions with the new aria_label parameter should have a @since notation in the docblock for the new param
  • added spaces between a few if(
  • tried to clarify some inline comments

#13 @sabernhardt
20 hours ago

@afercia 47123.2.diff looks good. Thanks!

Note: See TracTickets for help on using tickets.