The default block template used for menu blocks includes some accessibility enhancements so that the menu is semantically treated as a navigation landmark for screen readers and is labeled appropriately based on the title of the block:

{% set heading_id = attributes.id ~ '-menu'|clean_id %}
<nav role="navigation" aria-labelledby="{{ heading_id }}"{{ attributes|without('role', 'aria-labelledby') }}>
  {# Label. If not displayed, we still provide it for screen readers. #}
  {% if not configuration.label_display %}
    {% set title_attributes = title_attributes.addClass('visually-hidden') %}
  {% endif %}
  {{ title_prefix }}
  <h2{{ title_attributes.setAttribute('id', heading_id) }}>{{ configuration.label }}</h2>
  {{ title_suffix }}

  {# Menu. #}
  {% block content %}
    {{ content }}
  {% endblock %}
</nav>

The labeling part is sort of broken when the block is placed using Layout Builder and will cause issues if there's more than one menu output on the page. This is because the label of the block is assigned to the navigation landmark using an HTML ID, but the HTML ID is not set by Layout Builder. If instead the block is output using the block placement UI, the ID is set thanks to BlockViewBuilder.

So for Layout Builder, the template will include markup like this:

<nav role="navigation" aria-labelledby="-menu" data-block-plugin-id="menu_block:ps-utility-menu" class="block block-menu navigation menu--ps-utility-menu"> 
  <h2 id="-menu">Utility menu</h2>
  ...
</nav>

The ID is not unique anymore. Any additional menu blocks on the page will have the same "-menu" ID and screen readers won't handle this well.

I don't think layout builder should assign an ID attribute for every block, but it seems like in the case of menu blocks it needs to, since the menu block template assumes it is set.

Comments

bkosborne created an issue. See original summary.

kunalkapoor’s picture

Hi @bkosborne if you want an id of the block placed by layout builder you can use id="block-{{ elements.content['#block_content'].id() }}" this will give you a unique number for each block created by layout builder.

kunalkapoor’s picture

id-"block-{{ elements.content['#block_content'].id() }}"
May be this can solve your problem

bkosborne’s picture

Indeed, while this can be solved with template overrides, this can be fixed in out-of-the-box Drupal.

andrewmacpherson’s picture

Thanks for filing this @bkosborne.

The ID is not unique anymore. Any additional menu blocks on the page will have the same "-menu" ID and screen readers won't handle this well.

This is a bit vague. The actual problem lies with browsers, not screen readers. It's the browser's job to compute the accessible name of landmark regions; the screen reader just relays what it has been provided by the browser.

In practice, when an IDREF points to a non-unique ID, the first matching ID in the DOM order wins. The computed accessible names will be the same for all affected landmark regions, but only correct for one of them. To make matters worse, it's effectively random; we don't know what order the blocks have been placed in. If there is only one menu block placed by layout builder, this might not cause a problem at all.

Bumping to major, because it seriously confounds assistive tech users ability to understand the page structure or find what they need. Having incorrectly-named ARIA navigation landmarks is worse than having no accessible names at all. There are a bunch of relevant WCAG success criteria:

  • Clear failures of 4.1.1 Parsing (level A), 4.1.2 Name, Role, Value (level A), 2.4.1 Bypass Blocks (level AA), and 1.3.6 Identify Purpose (level AAA).
  • I'd probably count it as as a failure of SC 1.3.1 Info and Relationships (level A) too.
  • If there are a different set of layout builder menu blocks on different pages, it may result in a failure of SC 3.2.4 Consistent Identification (level AA) because a different block could win the "first duplicate ID in the DOM order" condition on different pages. Can't say this for sure though, because it depends on the actual site. The site-builder wouldn't be able to predict or control this easily though.

Note that an ID which begins with a hyphen was not valid under HTML 4 parsing rules, but is permitted by HTML 5. I don't know whether that makes any practical difference for actual browsers, but I'd suppose it's safer to stay clear of this situation.

andrewmacpherson’s picture

Priority: Normal » Major
mgifford’s picture

Version: 8.9.x-dev » 9.2.x-dev
mgifford’s picture

Issue tags: +vpat

Linking open issues from the CivicActions Accessibility - VPAT.

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.

kazah’s picture

Hello!

How do you use this id-"block-{{ elements.content['#block_content'].id() }}"

Where do you put this code?

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.

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.

mgifford’s picture

Issue tags: +wcag131
bensti’s picture

what happen with this issues?

this is not only the menu block. all my block place with Layout builder dont have any ID. only a ugly class : block-block-content52048ada-f924-4fb5-a0a0-ccd02ca9ccc5

any solution?

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’s picture

Status: Active » Closed (duplicate)

Thanks for raising an issue! In my opinion this is a duplicate issue of #3073895: System Menu blocks do not have attributes. That issue has an open MR and some further progress, so I'm closing this one as a duplicate.

Thanks!