Skip to content

Conversation

@im3dabasia
Copy link
Contributor

@im3dabasia im3dabasia commented Nov 8, 2024

What?

Fixes #64051.

Why?

This PR addresses accessibility by ensuring screen readers recognize these blocks as navigational elements, as per issue #64051.

How?

Added <nav> wrappers around the lists in core/page-list and core/tag-cloud blocks. For core/categories, the <nav> is conditionally added when displayed as a list (not as a dropdown), improving accessibility.

Screenshots or screencast

Before After
Before After

@github-actions github-actions bot added the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Nov 8, 2024
@github-actions
Copy link

github-actions bot commented Nov 8, 2024

👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @im3dabasia! In case you missed it, we'd love to have you join us in our Slack community.

If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information.

@im3dabasia im3dabasia marked this pull request as ready for review November 8, 2024 11:56
@im3dabasia im3dabasia requested a review from ajitbohra as a code owner November 8, 2024 11:56
@github-actions
Copy link

github-actions bot commented Nov 8, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: im3dabasia <[email protected]>
Co-authored-by: carolinan <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Co-authored-by: afercia <[email protected]>
Co-authored-by: joedolson <[email protected]>
Co-authored-by: Hug0-Drelon <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@skorasaurus skorasaurus added the [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). label Nov 8, 2024
@carolinan
Copy link
Contributor

carolinan commented Nov 10, 2024

Hi @im3dabasia I do not believe that this is the correct solution for this problem. I also believe that the problem and use case needs to be described in more detail before a solution can be proposed. I recommend allowing some more time to discuss the issue first.

The <nav> element is intended to be used for navigations, and all lists of links are not necessarily navigations.

Also when there is more than one nav on a page, visitors need to be able to distinguish one nav from the other.
Consider a scenario where the user adds both a tag cloud and categories block in the same post content or template.
The navigations need to have labels describing their purpose.


return sprintf(
'<p %1$s>%2$s</p>',
'<nav %1$s>%2$s</nav>',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works well in my test, but the nav needs a unique label. It also needs to take into the account that more than one of copy of the tag cloud block can be used on the same page.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @carolinan ,

I have addressed the changes you suggested earlier. Could you please guide me on the changes I need to make based on this comment? I am unsure.

@carolinan carolinan added the [Type] Enhancement A suggestion for improvement. label Nov 10, 2024
@im3dabasia
Copy link
Contributor Author

Thank you for the feedback, @carolinan! I'll hold off on any additional changes until there's further discussion on the issue's scope and proposed solution.

@carolinan
Copy link
Contributor

Thank you for the feedback, @carolinan! I'll hold off on any additional changes until there's further discussion on the issue's scope and proposed solution.

My concern is the page list block, if that can be separated I think work on the other two blocks can continue.

@im3dabasia
Copy link
Contributor Author

Thank you for the feedback, @carolinan! I'll hold off on any additional changes until there's further discussion on the issue's scope and proposed solution.

My concern is the page list block, if that can be separated I think work on the other two blocks can continue.

Thank you for the reply @carolinan.

I will start working on the other 2 blocks but I need some guidance. In the category list block. The suggestion was to change the constant tagName to 'nav' instead of 'ul', Here I had a doubt since the function renderCategoryList() returns a array of <li>( renderCategoryList calls renderCategoryListItem() internally). If I change the TagName to 'nav' then the generated markup would be

<nav>
<li> </li>
<li> </li>
<li> </li>
</nav>

This would result in wrong markup. I am confused here on how to approach this. Any guidance on this would be much appreciated

@carolinan
Copy link
Contributor

@im3dabasia I think you can change the <nav> element that you added around renderCategoryList() to a <ul>, and then change <ul> in the TagName constant to a nav?

@im3dabasia im3dabasia requested a review from carolinan December 3, 2024 03:34
@carolinan
Copy link
Contributor

I found that the tag cloud has a format parameter where developers can choose between an unordered list and a flat list of items. But both formats can be inside a <nav> without any validation problems. https://developer.wordpress.org/reference/functions/wp_tag_cloud/

There aren't many examples of adding aria labels that are editable by the user. The navigation block uses one, and there is a suggestion to add one to the group block.

  1. ariaLabel is a block support, it needs to be set to true in block.json.
  2. After updating the block support, the documentation also needs to be updated. npm run docs:build.
  3. The option needs to be a text input field in the Advanced section of the InspectorControls.
  4. The option needs a suitable default value for when the user does not customize the label.
  5. The option needs a suitable label. The label for the option in the navigation block is "Menu name" , so perhaps "Tag Cloud name"?

The categories are different because it already has a label text that is used when the dropdown option is selected.
This label text could be re-used as the aria label on the nav.

@im3dabasia
Copy link
Contributor Author

Hey @carolinan

I am new to contributing and just want to verify if I need to do the following:

a) Enable ariaLabel support in block.json.
b) Add a text input field for the aria-label in the Advanced section of InspectorControls, ensuring it has appropriate default values and labels.
c) Update the documentation after the changes by running npm run docs:build.

Please let me know if I’m on the right track or if there’s anything I’m missing.

@carolinan
Copy link
Contributor

Yes.
But also be prepared that there may be more discussions and reviews since this is not a common pattern in the existing blocks.

@carolinan carolinan added [Block] Tag Cloud Affects the Tag Cloud Block [Block] Categories Affects the Categories Block labels Dec 3, 2024
@im3dabasia
Copy link
Contributor Author

Hi @carolinan,

I have implemented the requested changes and added support for the aria-label, allowing the user to customize it. By default, the name is set to "Tag Cloud", but the user has the option to modify it in the Advanced section of the Inspector Controls.

Attaching a video reference for the same:

Screen.Recording.2024-12-06.at.4.26.43.PM.mov

Please take a look at the changes, and I would appreciate any feedback you may have.

Thank you!

@im3dabasia
Copy link
Contributor Author

Hi @carolinan,
When you have a moment, could you please review my PR and provide feedback on how I can improve it?

function render_block_core_tag_cloud( $attributes ) {
$smallest_font_size = $attributes['smallestFontSize'];
$unit = ( preg_match( '/^[0-9.]+(?P<unit>[a-z%]+)$/i', $smallest_font_size, $m ) ? $m['unit'] : 'pt' );
$aria_label = isset( $attributes['ariaLabel'] ) ? $attributes['ariaLabel'] : 'Tag Cloud';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default text must be translatable, placed inside a translation function.

@carolinan
Copy link
Contributor

Please solve the merge conflict first :)

@t-hamano
Copy link
Contributor

t-hamano commented Feb 6, 2025

This comment made me realize that the aria-label support is not complete. We are currently discussing how to address this in #68764.


About this PR: My biggest concern is backwards compatibility.

This PR changes the structure of the output HTML, which may have a significant impact on themes that already apply styles to these blocks via stylesheets.

If we replace the block wrapper element itself with a nav element

The HTML will change as follows:

<!-- From -->
<p class="wp-block-tag-cloud">
	<a href="">Tag</a>
</p>

<!-- To -->
<nav class="wp-block-tag-cloud">
	<a href="">Tag</a>
</nav>

Selectors like p.wp-block-cloud will no longer work.

If we wrap the block wrapper element in a nav element

The HTML will change as follows:

<!-- From -->
<p class="wp-block-tag-cloud">
	<a href="">Tag</a>
</p>

<!-- To -->
<nav>
	<p class="wp-block-tag-cloud">
		<a href="">Tag</a>
	</p>
</nav>

Selectors like .entry-content > .wp-block-cloud will no longer work. This may also affect margin support, layout, etc.

With this in mind, I think we need to have more discussion before moving forward, taking into account the impact on backward compatibility.

@carolinan
Copy link
Contributor

Its not great but the accessibility is more important.

@t-hamano
Copy link
Contributor

t-hamano commented Feb 6, 2025

I agree that accessibility is important, but we cannot ignore the impact on backward compatibility for that reason. I think we need to investigate in advance how much of an impact it will have.

In any case, ariaLabel block support in dynamic blocks is not complete, so we may need to fix that first.

@carolinan
Copy link
Contributor

I did a quick search on wpdirectory.net, which does not replace doing more research:
.wp-block-tag-cloud is in 1559 themes.
p.wp-block-tag-cloud is in 281 themes and 1 plugin.

Copy link
Contributor

@t-hamano t-hamano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we proceed with this PR, I recommend that you thoroughly investigate the impact of this change, along with accessibility feedback. For example:

  • Is the global styles applied correctly?
  • Are there any visual changes in the default theme?
  • Are block support, especially spacing support, applied correctly?

Additionally, we should consider the impact of selectors like the following if a theme uses them:

  • .wp-block-categories-list > li
  • .wp-block-categories > li
  • .wp-block-tag-cloud > a

@im3dabasia im3dabasia requested a review from t-hamano February 24, 2025 11:50
@t-hamano
Copy link
Contributor

t-hamano commented Mar 3, 2025

I want to reaffirm whether moving forward with this PR approach is truly important from an accessibility perspective.

This PR will result in the following changes to the HTML:

Tag Cloud Block

<!-- From -->
<p class="wp-block-tag-cloud">
  <a href="" class="tag-cloud-link" aria-label="Tag A (1 item)">Tag A</a>
  <a href="" class="tag-cloud-link" aria-label="Tag B (1 item)">Tag B</a>
  <a href="" class="tag-cloud-link" aria-label="Tag C (1 item)">Tag C</a>
</p>

<!-- To -->
<nav class="wp-block-tag-cloud" aria-label="Tag Cloud">
  <a href="" class="tag-cloud-link" aria-label="Tag A (1 item)">Tag A</a>
  <a href="" class="tag-cloud-link" aria-label="Tag B (1 item)">Tag B</a>
  <a href="" class="tag-cloud-link" aria-label="Tag C (1 item)">Tag C</a>
</nav>

Categories Block (as a list)

<!-- From -->
<ul class="wp-block-categories-list wp-block-categories">
  <li class="cat-item cat-item-1"><a href="">Category A</a></li>
  <li class="cat-item cat-item-2"><a href="">Category B</a></li>
  <li class="cat-item cat-item-3"><a href="">Category C</a></li>
</ul>

<!-- To -->
<nav class="wp-block-categories-list wp-block-categories">
  <ul>
    <li class="cat-item cat-item-1"><a href="">Category A</a></li>
    <li class="cat-item cat-item-2"><a href="">Category B</a></li>
    <li class="cat-item cat-item-3"><a href="">Category C</a></li>
  </ul>
</nav>

My concerns are:

  • Do these blocks need to be wrapped in a nav element?
  • Are nav elements without aria-label acceptable?
  • If nav elements without aria-label are not acceptable, do we need to expose the aria-label editing UI?
  • Blocks may be duplicated and have the same aria-label.

cc @afercia @joedolson @alexstine

@afercia
Copy link
Contributor

afercia commented Mar 3, 2025

whether moving forward with this PR approach is truly important from an accessibility perspective

I would say that at the very least the related blocks should provide feature parity with what was implemented in Core, although the Core implementation is behind opting-in for html5 support for navigation-widgets. Reference:

https://make.wordpress.org/core/2020/07/09/accessibility-improvements-to-widgets-outputting-lists-of-links-in-5-5/
https://core.trac.wordpress.org/ticket/48170
https://core.trac.wordpress.org/changeset/48349

Are nav elements without aria-label acceptable?

A nav element without appropriate labeling is only acceptable if there's only one nav element on a page.
If I remember correctly, the Core implementation for the classic widgets does allow to pass an aria-label and provides a default one.

@joedolson
Copy link
Contributor

If a block is duplicated and has the same label, that's OK; a block with the same content is semantically the same block, so a duplicate label is accurate.

I would say that yes, they should be wrapped in nav elements. Like @afercia says, having feature compatibility with the core widgets is the base line, and those are wrapped in nav elements.

However, I note that while block themes mostly declare HTML5 by default, they are omitting the navigation widgets from that declaration; is that an oversight?

See: r52439 & https://github.com/WordPress/wordpress-develop/blob/b5e0c16c04edcebdf5e81c39796a9d2c22cfd6f7/src/wp-includes/theme.php#L4394

@carolinan
Copy link
Contributor

If a block is duplicated and has the same label, that's OK; a block with the same content is semantically the same block, so a duplicate label is accurate.

Aha, yes that makes sense, thank you,

@carolinan
Copy link
Contributor

However, I note that while block themes mostly declare HTML5 by default, they are omitting the navigation widgets from that declaration; is that an oversight?

See: r52439 & https://github.com/WordPress/wordpress-develop/blob/b5e0c16c04edcebdf5e81c39796a9d2c22cfd6f7/src/wp-includes/theme.php#L4394

I am not sure what a navigation widget is.

@afercia
Copy link
Contributor

afercia commented Mar 5, 2025

I am not sure what a navigation widget is.

navigation-widgets is one of the extra arguments for add_theme_support( 'html5', $args ). When supported, many classic widgets like the navigation menu widget, archives, categories, pages, recent posts, recent comments etc. wrap their html output within a labeled <nav> element.

As @joedolson pointed out, it appears block themes do not support the full 'html5 support' extra arguments as navigation-widgets is missing from the extra args array here.

@carolinan
Copy link
Contributor

But where is it documented? it is not listed here under the html5 heading. https://developer.wordpress.org/reference/functions/add_theme_support/

@carolinan
Copy link
Contributor

Yeah I would assume it was unintentionally missed because it is not clearly documented.

@afercia
Copy link
Contributor

afercia commented Mar 5, 2025

Yeah I would assume it was unintentionally missed because it is not clearly documented.

I guess so. I see the REST API doesn't support it as well? This new support was intended to be fully 'opt-in' but I'm not sure why it hasn't been documented.

@joedolson
Copy link
Contributor

I feel like we need an option that allows a user to just pass 'all' or true to support all HTML5 options. The need to specifically iterate each individual support makes sense for older themes to have a gradual migration path, but it just creates extra labor and complication for most modern use cases.

Added a core ticket to propose this.

@t-hamano
Copy link
Contributor

t-hamano commented Mar 6, 2025

Thanks everyone for your feedback!

I would say that at the very least the related blocks should provide feature parity with what was implemented in Core, although the Core implementation is behind opting-in for html5 support for navigation-widgets. Reference:

Does this mean that if a theme doesn't have html5 theme support, we shouldn't use nav elements?

If so, I'm wondering if this argument applies to other blocks as well. For example:

@carolinan
Copy link
Contributor

carolinan commented Mar 6, 2025

Does this mean that if a theme doesn't have html5 theme support, we shouldn't use nav elements?

No, the blocks should use modern HTML that is supported by the browsers that WordPress requires.

@carolinan
Copy link
Contributor

The HTML theme support exists to make it easier for theme developers to use modern HTML, while keeping the features backwards compatible with older themes that has styles that expects a certain markup. As seen here: https://core.trac.wordpress.org/ticket/61183

@afercia
Copy link
Contributor

afercia commented Mar 6, 2025

Does this mean that if a theme doesn't have html5 theme support, we shouldn't use nav elements?

Ideally, blocks themes (and thus the blocks they use) should output modern html5 markup and use best practices by default. as @carolinan pointed out, the html5 support was introduced many years ago to allow themes to progressively, granularly, introduce new html5 features. I think blocks should support all these html5 features by default.

@t-hamano t-hamano removed the First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository label Aug 19, 2025
@t-hamano
Copy link
Contributor

Sorry for the late reply.

I thought about how we could move this PR forward. I think it may be good to focus on just adding a wrapper nav element with the hard-coded aria-label text.

That is, remove the aria-label support from the Tag Cloud block. There is no block that exposes the aria-label editing UI, so it would need to be discussed more deeply. Additionally, I'm not sure if any users would want to change the aria-abel text, as both blocks have an obvious purpose.

I think the key here is probably to see what visual changes occur in the default themes.

Let me know what you think!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Block] Categories Affects the Categories Block [Block] Tag Cloud Affects the Tag Cloud Block [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Accessibility issue with links listing blocks.

6 participants