When a menu block is placed using Layout Builder, the rendering of the HTML ID attribute is missing a unique identifier, resulting in an "incomplete" -menu suffix. This is impactful because if two such menu blocks are placed on the same page, it will result in two identical HTML attributes, which is invalid markup and has accessibility implications (e.g., https://www.w3.org/WAI/WCAG21/Techniques/html/H93).

Example output:

<nav role="navigation" aria-labelledby="-menu" data-layout-content-preview-placeholder-label="&quot;Main navigation&quot; block" class="block block-menu navigation menu--main">
      
  <h2 id="-menu">Main navigation</h2>
  
...

Steps to Reproduce

1. Enable Layout Builder on a node type.
2. Place a menu block into a node layout using the Layout Builder interface.
3. Inspect the menu block output. Note that the id is always -menu as is the aria-labelledby

Impact

If two instances of the menu block are placed, this will result in duplicate HTML ID attributes, resulting in inaccessible markup.

Proposed resolution

Update the SystemMenuBlock block plugin to supply a unique ID attribute by default. This ID will be used by existing templates to populate the ID attribute associated with the block title as well as the aria-labelledby attribute that points to that HTML ID.

Acceptance criteria

When a menu block is placed on a page using Layout Builder, it has markup that includes a valid, unique HTML ID attribute as well as an aria-labelledby attribute that matches that HTML ID value.

Issue fork drupal-3073895

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

meecect created an issue. See original summary.

tim.plunkett’s picture

Version: 8.7.x-dev » 8.8.x-dev
Status: Active » Needs review
Issue tags: +Blocks-Layouts
Related issues: +#3003610: Remove block.module dependency from Layout Builder
StatusFileSize
new811 bytes

Here's a patch. Not really helpful for anyone, as it uses a UUID. But at least the markup is valid.

Note that this is really a bug in block module for wrongly assuming there will be an ID available...

Status: Needs review » Needs work

The last submitted patch, 2: 3073895-id-2.patch, failed testing. View results

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

rishabhthakur’s picture

Assigned: Unassigned » rishabhthakur
rishabhthakur’s picture

Status: Needs work » Needs review
StatusFileSize
new853 bytes

Review Original patch https://www.drupal.org/files/issues/2019-08-12/3073895-id-2.patch it was written in wrong way to attached ID attributes with Block.
New Patch applied & tested with drupal 8.9.x , 9.0.x & 9.1.x versions
its working fine

Please review and confirm

Status: Needs review » Needs work

The last submitted patch, 7: layout-builder-blocks-id-3073895-7.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

rishabhthakur’s picture

StatusFileSize
new857 bytes
new2.14 KB

Upload Interdiff for last patch with new patch

rishabhthakur’s picture

Assigned: rishabhthakur » Unassigned

On Code base its working but as Test cases fail so maybe we need to change on Test case

Correct me if I'm wrong.

Need Review on patch & test cases

rishabhthakur’s picture

Issue tags: +Needs tests
ramya balasubramanian’s picture

Assigned: Unassigned » ramya balasubramanian
ramya balasubramanian’s picture

Status: Needs work » Needs review
StatusFileSize
new3.41 KB

Fixing test cases file.

ramya balasubramanian’s picture

Hi,
I have missed this function testContextAwareBlock in the previous patch. Updated the patch again.

The last submitted patch, 13: system-menu-blocks-do-not-have-attributes-3073895-13.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 14: system-menu-blocks-do-not-have-attributes-3073895-14.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

ramya balasubramanian’s picture

ramya balasubramanian’s picture

Assigned: ramya balasubramanian » Unassigned
Status: Needs work » Needs review
StatusFileSize
new3.72 KB

Fixing the test cases on section render test file.

ramya balasubramanian’s picture

Fixing code standards.

Status: Needs review » Needs work
ramya balasubramanian’s picture

Status: Needs work » Needs review
StatusFileSize
new3.72 KB
new837 bytes

Fixing the coding standard.

tim.plunkett’s picture

Status: Needs review » Needs work

NW for the missing test coverage.
Also #21 was the opposite, there should be spaces there

ramya balasubramanian’s picture

Apologies for the late reply @tim.plunket was bit occupied. I guess the test cases were already present. I didn't get your comment about test cases. Can you please tell me which test cases you are talking about.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

jay.dansand’s picture

Simple re-roll of the patch from #21 so it applies cleanly with composer-patches on 9.3.x and 9.4.x. No interdiff because no code lines changed, only surrounding context.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

bradallenfisher’s picture

latest patch doesn't apply to 9.5

_utsavsharma’s picture

StatusFileSize
new3.69 KB
new3.69 KB

Patch for 9.5.x.

_utsavsharma’s picture

Status: Needs work » Needs review
bradallenfisher’s picture

the patch in #32 applies cleanly and the functionality has returned. thanks!

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

For the specific test coverage still needed.

Also I see that the tests were updated is that because this attribute is now required? Won't this break existing sites that don't have it?

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

DanielVeza made their first commit to this issue’s fork.

danielveza’s picture

Status: Needs work » Needs review

Opened an MR with a slightly different approach.

The existing patch will add an ID to every since block that is added via LB, which feels a bit overkill to solve this. Instead I've added a default ID that will be applied to system_menu_blocks if one does not exist. If people like this approach I'll add some tests

needs-review-queue-bot’s picture

Status: Needs review » Needs work

The Needs Review Queue Bot tested this issue.

While you are making the above changes, we recommend that you convert this patch to a merge request. Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)

danielveza’s picture

danielveza’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work

Seems a few other block--system-menu-block.html.twig in core. Is there a place we can add an assertion to?

mark_fullmer made their first commit to this issue’s fork.

mark_fullmer’s picture

Status: Needs work » Postponed

This appears no longer to be an issue as of 11.3.x. Placing a menu block on the page successfully generates unique ID attributes; placing a second instance of the same menu block confirms that the ID attributes and corresponding aria-labelledby attributes are unique. I haven't tracked down the core commit responsible for this yet, but will set this to "Postponed" given the above.

Example markup of first instance of menu block:

<nav id="block-olivero-mainnavigation" class="contextual-region primary-nav block block-menu navigation menu--main" aria-labelledby="block-olivero-mainnavigation-menu" role="navigation">
      
  <h2 class="block__title" id="block-olivero-mainnavigation-menu">Main navigation</h2>

Example markup of second instance of menu block:

<nav id="block-olivero-mainnavigation-2" class="contextual-region primary-nav block block-menu navigation menu--main" aria-labelledby="block-olivero-mainnavigation-2-menu" role="navigation">
      
  <h2 class="block__title" id="block-olivero-mainnavigation-2-menu">Main navigation</h2>

mark_fullmer’s picture

Title: System Menu blocks do not have attributes » System Menu blocks placed via Layout Builder do not have attributes
Issue summary: View changes
Status: Postponed » Needs review
Issue tags: +Accessibility

My previous comment was wrong. This is still an issue in Drupal core, though it only manifests in the context of placing a menu block using Layout Builder.

mark_fullmer’s picture

Version: 11.x-dev » 11.2.x-dev

Seems a few other block--system-menu-block.html.twig in core. Is there a place we can add an assertion to?

Agreed that modifying the Twig templates is not the best approach here. Instead, we can supply the ID attribute to all templates through the SystemMenuBlock::build() method. The rendering logic for a unique ID can be modeled exactly on block/src/Hook/BlockHooks::preprocessBlock(), per below:

    // Create a valid HTML ID and make sure it is unique.
    if (!empty($variables['elements']['#id'])) {
      $variables['attributes']['id'] = Html::getUniqueId('block-' . $variables['elements']['#id']);
    }

I've created an alternate merge request, at https://git.drupalcode.org/project/drupal/-/merge_requests/12664

themusician’s picture

StatusFileSize
new134.85 KB

The latest patch appears to work. This is a screenshot of the code output when two unique menu blocks are inserted on the same page via layout builder.

Screenshot of HTML output by two menu blocks inserted.

smustgrave’s picture

Status: Needs review » Needs work

Nice! Glad we found a non template approach.

Moving to NW for the test coverage also issue summary may need some love to include proposed solution and maybe screenshots.

Thanks!

mark_fullmer changed the visibility of the branch 3073895-system-menu-blocks to hidden.

mark_fullmer’s picture

Version: 11.2.x-dev » 11.x-dev

mark_fullmer changed the visibility of the branch 3073895-blocks-unique-id to hidden.

mark_fullmer’s picture

Title: System Menu blocks placed via Layout Builder do not have attributes » System Menu blocks placed via Layout Builder can generate duplicate, invalid HTML ID attributes
Issue summary: View changes
mark_fullmer’s picture

Issue summary: View changes
mark_fullmer’s picture

Issue summary: View changes
danielveza’s picture

+1 on the approach from the latest MR. Looks like the newly added test coverage is failing to find the newly added ID though. I expect it will be a quick fix.

mark_fullmer changed the visibility of the branch 3073895-layout-builder-menu-blocks to hidden.

mark_fullmer changed the visibility of the branch 3073895-layout-builder-menu-blocks to active.

mark_fullmer’s picture

Status: Needs work » Needs review

Updated to accommodate tests! Ready for further review.

danielveza’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

Nice. Given it a (hopefully) last review. No issues, reckon this can be RTBC.

nod_’s picture

Status: Reviewed & tested by the community » Needs review

I'm not sure the fix is appropriate.

IDs are not a backend concern, so it seems strange to handle that in the backend when the frontend can deal with it, we try not to rely on ids for styling and JS so the id could be random and it'd still work.

The MR https://git.drupalcode.org/project/drupal/-/merge_requests/6965 looks promising need to use |clean_unique_id to make sure things don't break when you're dealing with ajax stuff.

mark_fullmer’s picture

we try not to rely on ids for styling and JS so the id could be random and it'd still work.

Indeed, separate from styling and JS targets, HTML ID attributes, especially, as in this case, when associated with HTML heading tags, are used as in-page anchor links. Having a "permalink" through a consistent HTML ID, therefore, is preferable to a random one.

The approach in https://git.drupalcode.org/project/drupal/-/merge_requests/6965 would seem to provide a consistent ID, so if the Drupal core practice is to register HTML IDs in Twig templates, then MR 6965 would seem to be the right approach.

The disadvantage, for the sake of stating it explicitly, of updating (multiple) core Twig templates is that any sites that have defined their own block--system-menu-block templates will not receive this change. In my experience in Drupal development, the menu block template is frequently modified on a per site basis.

mark_fullmer changed the visibility of the branch 3073895-system-menu-blocks to active.

daddison made their first commit to this issue’s fork.

daddison’s picture

I updated https://git.drupalcode.org/project/drupal/-/merge_requests/6965 to use |clean_unique_id twig filter in the block and updated test coverage.

smustgrave’s picture

Original concern of updating the the twig templates directly is back. We will need a CR as contrib and custom themes won't have that change.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs change record

If we are going to go the template route think we need a CR to least alert others that have overridden this template.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

mh_nichts’s picture

Hello,
I wanted to warn that https://git.drupalcode.org/project/drupal/-/merge_requests/6965 is acting only on the heading_id (which is used to "label" the navigation via aria-labelledby), but it's not acting on the block id itself (attributes.id).
It seems to me that https://git.drupalcode.org/project/drupal/-/merge_requests/12806 is acting at the right place, before Twig rendering, and really on the block id itself : I agree with https://www.drupal.org/project/drupal/issues/3073895#comment-16254500 about the necessary separating of concerns.