Problem/Motivation

Drupal's page template has several regions with the landmark role: <aside role="complementary">.

The WAI-ARIA Authoring Practices recommends giving these accessible names. Currently, ours do not.


Accessible Name Guidance by Role

  • Naming is necessary when two complementary landmark regions are present on the same page.
  • Naming is recommended even when one complementary region is present to help users understand the purpose of the region's content when navigating among landmark regions.
  • Use aria-labelledby if a visible label is present, otherwise use aria-label.

Proposed resolution

Add accessible names to the theme regions. For example: <aside role="complementary" aria-label="First sidebar">

Problem:

What names will we use for the complementary landmarks?

The names of the theme regions are almost a good fit, but not exactly. Some tweaks are needed:

  1. Bartik has several regions called "Featured bottom first", etc, but these are all wrapped up in a single landmark region. So we can call that one "Featured Bottom".
  2. The "First sidebar" and "Second sidebar" names are potentially confusing:
    • If there's only one sidebar, and it's called "first sidebar", that sets up the expectation that there is another one.
    • Even worse, if there's only one sidebar, but it's called "second sidebar", then that would be even more confusing.

    To address this, we can make the name conditional:

    • If there is only one sidebar, call it "sidebar".
    • If both sidebars are present, use the names "first sidebar" and "second sidebar".

    There is already some code in which adds CSS classes based on the number of sidebars, so a similar approach could be used to create conditional aria-label attributes for the sidebars.

Remaining tasks

  • Figure out the names to use. DONE, see comments #7-8.
  • Patch the page templates. See the file list in comment #5.

User interface changes

No visible changes. Addition of accessible names for assistive technology.

API changes

None expected.

Data model changes

None expected.

Release notes snippet

Comments

andrewmacpherson created an issue. See original summary.

xjm’s picture

Category: Feature request » Task
andrewmacpherson’s picture

Category: Task » Bug report

Ooh, I forgot I filed this!

Thinking about it, this should probably be classed as a bug report, on the basis that the W3C ARIA Authoring Practices says "Naming is necessary when two complementary landmark regions are present on the same page" (emphasisi mine).

This might be a somewhat disruptive for a patch release, depending on how we implement it. We'll see.

We could split this into child issues for each theme if needs be.

andrewmacpherson’s picture

Issue summary: View changes

minor issue summary updates

andrewmacpherson’s picture

Issue tags: +Novice

I looked over all the variants of page.html.twig in core.

ALL of the complementary landmarks are hard-coded HTML elements with no dynamic twig variables (e.g. attributes) in the tag. This example comes from Bartik, and is typical:

        <aside class="layout-container section clearfix" role="complementary">

This is good news for backwards compatibility - the fact that none of these instances have any twig variables in the tag means that the only way this could have been fixed in an existing website was by overriding (or hacking) the Twig template. I think that means we can introduce an aria-label="First sidebar" attribute without worrying about disrupting existing sites. That includes the Classy, Stable, and Stable9 themes; non-disruptive accessibility fixes have been permitted in these templates in the past.

So the only outstanding question is to figure out what to call a few of the regions.

Here's the full list of complementary landmark regions in theme templates. Output of ack --type=twig --sort-files "complementary":

core/modules/system/templates/install-page.html.twig
38:      <aside class="layout-sidebar-first" role="complementary">
44:      <aside class="layout-sidebar-second" role="complementary">

core/modules/system/templates/maintenance-page.html.twig
45:  <aside role="complementary">
51:  <aside role="complementary">

core/modules/system/templates/page.html.twig
71:      <aside class="layout-sidebar-first" role="complementary">
77:      <aside class="layout-sidebar-second" role="complementary">

core/profiles/demo_umami/themes/umami/templates/classy/layout/maintenance-page.html.twig
48:    <aside class="layout-sidebar-first" role="complementary">
54:    <aside class="layout-sidebar-second" role="complementary">

core/profiles/demo_umami/themes/umami/templates/layout/page.html.twig
115:      <aside class="layout-sidebar" role="complementary">

core/themes/bartik/templates/page.html.twig
64:        <aside class="layout-container section clearfix" role="complementary">
71:        <aside class="featured-top__inner section layout-container clearfix" role="complementary">
87:            <aside class="section" role="complementary">
94:            <aside class="section" role="complementary">
103:        <aside class="layout-container clearfix" role="complementary">

core/themes/claro/templates/install-page.html.twig
26:    <aside class="layout-sidebar-first" role="complementary">
40:    <aside class="layout-sidebar-second" role="complementary">

core/themes/claro/templates/maintenance-page.html.twig
21:    <aside class="layout-sidebar-first" role="complementary">

core/themes/classy/templates/layout/maintenance-page.html.twig
48:    <aside class="layout-sidebar-first" role="complementary">
54:    <aside class="layout-sidebar-second" role="complementary">

core/themes/classy/templates/layout/page.html.twig
68:      <aside class="layout-sidebar-first" role="complementary">
74:      <aside class="layout-sidebar-second" role="complementary">

core/themes/seven/templates/install-page.html.twig
26:    <aside class="layout-sidebar-first" role="complementary">
40:    <aside class="layout-sidebar-second" role="complementary">

core/themes/seven/templates/maintenance-page.html.twig
21:    <aside class="layout-sidebar-first" role="complementary">

core/themes/stable/templates/layout/install-page.html.twig
36:      <aside class="layout-sidebar-first" role="complementary">
42:      <aside class="layout-sidebar-second" role="complementary">

core/themes/stable/templates/layout/maintenance-page.html.twig
43:  <aside role="complementary">
49:  <aside role="complementary">

core/themes/stable/templates/layout/page.html.twig
69:      <aside class="layout-sidebar-first" role="complementary">
75:      <aside class="layout-sidebar-second" role="complementary">

core/themes/stable9/templates/layout/install-page.html.twig
36:      <aside class="layout-sidebar-first" role="complementary">
42:      <aside class="layout-sidebar-second" role="complementary">

core/themes/stable9/templates/layout/maintenance-page.html.twig
43:  <aside role="complementary">
49:  <aside role="complementary">

core/themes/stable9/templates/layout/page.html.twig
69:      <aside class="layout-sidebar-first" role="complementary">
75:      <aside class="layout-sidebar-second" role="complementary">
andrewmacpherson’s picture

Issue summary: View changes
maxstarkenburg’s picture

A few comments from a Slack discussion on this:

Minor point, but the <aside> in Bartik for featured_bottom_... regions at least wraps all three in one, so a default for that particular one could at least presumably be a simpler "Featured bottom".

Assuming some defaults really are needed, it would be a better experience for a screen reader user to only hear something like "First sidebar" on pages where more than one sidebar is used (and otherwise just hear "Sidebar" if it's the only one, lest they wonder why they can't find the second one), and as mentioned in the Slack thread, it would be even more confusing if "Second sidebar" was output on pages that didn't have a first sidebar to begin with. But obviously adding such conditionals would make any patches a bit more complex.

As Andrew also mentioned in Slack, sites in RTL languages might also add a wrinkle (though maybe other parts of core are already doing a good enough job of not assuming sidebar-first is necessarily on the left?).

andrewmacpherson’s picture

Issue summary: View changes

@maxstarkenburg - thanks for adding your insights here. It was a productive Slack chat.

Minor point, but the in Bartik for featured_bottom_... regions at least wraps all three in one, so a default for that particular one could at least presumably be a simpler "Featured bottom".

I think this pretty much solves that problem! I noticed the same thing when I did the survey in #5.

The discussion about the "first sidebar" and "second sidebar" names was very useful. I think it's definitely worth putting the conditional names in place to avoid this confusion. Bartik already has some code which adds some CSS classes based on the number of sidebars present, so a similar approach should be achievable for the accessible names of the landmark regions.

As Andrew also mentioned in Slack, sites in RTL languages might also add a wrinkle (though maybe other parts of core are already doing a good enough job of not assuming sidebar-first is necessarily on the left?).

Yeah, my idea was to check the language direction so they can be conditionally named "left sidebar" and "right sidebar". I'm less convinced by that idea though, because the sidebars are moved below the main content on narrow viewports. Let's park that idea.

Updating the proposed resolution. Crediting @maxstarkenburg.

andrewmacpherson’s picture

Issue summary: View changes
andrewmacpherson’s picture

abhisekmazumdar’s picture

Assigned: Unassigned » abhisekmazumdar
abhisekmazumdar’s picture

Status: Active » Needs review
StatusFileSize
new17.61 KB

I have created a patch here Kindly review
I have a few points to make about it:

1. The themes which doesn't have first and second sidebar region like umami, seven, claro.
2. classy will be removed from Drupal 9. So think there's no need to do the changes.
3. Do the sidebar first & second things needed to be taken care on the stable base themes?

Kindly give your feedback. Thank You

Status: Needs review » Needs work

The last submitted patch, 12: add_accessible_names-3105316-12.patch, failed testing. View results

abhisekmazumdar’s picture

Assigned: abhisekmazumdar » Unassigned
Issue tags: +Needs tests
kostyashupenko’s picture

1.

+ $variables['page']['sidebar_first']['aria_label'] = 'First Sidebar';
+ $variables['page']['sidebar_second']['aria_label'] = 'Second Sidebar';

You missed translations for aria-labels.

2.

   {% if page.sidebar_first %}
-    <aside class="layout-sidebar-first" role="complementary">
+    <aside class="layout-sidebar-first" role="complementary" aria_label="Sidebar">
       {{ page.sidebar_first }}

Replace aria_label by aria-label in twig files

prabha1997’s picture

Assigned: Unassigned » prabha1997
prabha1997’s picture

Assigned: prabha1997 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new17.61 KB
new14.51 KB

Replace aria_label by aria-label in twig files.
I did above point. Kindly review patch

Status: Needs review » Needs work

The last submitted patch, 17: 3105316-17.patch, failed testing. View results

piyuesh23’s picture

Issue tags: +DIACWApril2020
druprad’s picture

Assigned: Unassigned » druprad
druprad’s picture

Assigned: druprad » Unassigned
sja112’s picture

Assigned: Unassigned » sja112
xjm’s picture

Version: 9.0.x-dev » 9.1.x-dev
sja112’s picture

Status: Needs work » Needs review
StatusFileSize
new17.65 KB

Updated patch and replaced aria_label by aria-label in twig files, also updated code in preprocess hook to eradicate the issue coming up in testing.
Please review.

Status: Needs review » Needs work

The last submitted patch, 24: 3105316-24.patch, failed testing. View results

sja112’s picture

Status: Needs work » Needs review
StatusFileSize
new15 KB

Updated patch to resolve the failed test case issue.

Drupal\KernelTests\Core\Theme\ConfirmClassyCopiesTest::testClassyHashes this case failed because as suggested,

If a copied Classy asset is changed, it should no longer be in a /classy 
subdirectory. The files there should be exact copies from Classy. Once it has 
changed, it is custom to the theme and should be moved to a different 
location.

Changes reverted from the classy theme.

abhisekmazumdar’s picture

Assigned: sja112 » Unassigned
Status: Needs review » Reviewed & tested by the community

Looks good to me.

xjm’s picture

Normally, we would not change the stable templates, but since this is an accessibility fix, there's a chance of doing this in a minor release. I especially think their might be an opportunity to make this change in Stable 9 before RC so that this is present throughout D9 without disrupting that base theme.

I'm less sure about whether it's safe to make the change in the D8 version of Stable; that's up to the frontend framework manager. So tagging for that review.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/system/templates/install-page.html.twig
    @@ -35,13 +35,13 @@
    +      <aside class="layout-sidebar-first" role="complementary" aria-label="{{ page.sidebar_first['#aria_label'] }}">
             {{ page.sidebar_first }}
    ...
    +      <aside class="layout-sidebar-second" role="complementary" aria-label="{{ page.sidebar_second['#aria_label'] }}">
             {{ page.sidebar_second }}
    
    +++ b/core/modules/system/templates/maintenance-page.html.twig
    @@ -42,13 +42,13 @@
    +  <aside role="complementary" aria-label="{{ page.sidebar_first['#aria_label'] }}">>
         {{ page.sidebar_first }}
    ...
    +  <aside role="complementary" aria-label="{{ page.sidebar_second['#aria_label'] }}">>
         {{ page.sidebar_second }}
    

    We might be able to find a better way to pass the labels to the template. These will stay in the render array when the region is being rendered. Maybe we can just move the string to templates?

  2. Let's make sure all the new strings have been passed through t() function.

sja112’s picture

Status: Needs work » Needs review
StatusFileSize
new13.19 KB

Hi @laurii,

Thanks for reviewing the patch.

I have updated the patch to add the suggested changes. I have passed the new strings through t() function. I have handled the addition of aria-label in twigs itself instead of adding them in a render array.

sja112’s picture

StatusFileSize
new16.26 KB

Adding interdiff file.

andrewmacpherson’s picture

Status: Needs review » Needs work

Thanks for working on this everybody. I've skim-read the latest patch, but I haven't manually tested each theme yet. I'll give it some manual testing soon.

Partial review of patch #30:

  1. I really like the simplicity of this approach: aria-label="{{ page.sidebar_first ? 'Second Sidebar'|t : 'Sidebar'|t }}".
  2. 
    diff --git a/core/modules/system/templates/page.html.twig b/core/modules/system/templates/page.html.twig
    index 032b724dfe..701758ad9b 100644
    --- a/core/modules/system/templates/page.html.twig
    +++ b/core/modules/system/templates/page.html.twig
    @@ -68,13 +68,13 @@
         </div>{# /.layout-content #}
    
         {% if page.sidebar_first %}
    -      <aside class="layout-sidebar-first" role="complementary">
    +      <aside class="layout-sidebar-first" role="complementary" aria-label="{{ page.sidebar_second ? 'First Sidebar'|t : 'Sidebar'|t }}}">>

    There's a Twig syntax error in this instance. Notice there are 3 curly braces (}}}) at the end of the aria-label.

  3. diff --git a/core/modules/system/templates/maintenance-page.html.twig b/core/modules/system/templates/maintenance-page.html.twig
    index 748ed5a3aa..781e611d80 100644
    --- a/core/modules/system/templates/maintenance-page.html.twig
    +++ b/core/modules/system/templates/maintenance-page.html.twig
    @@ -42,13 +42,13 @@
     </main>
    
     {% if page.sidebar_first %}
    -  <aside role="complementary">
    +  <aside role="complementary" aria-label="{{ page.sidebar_second ? 'First Sidebar'|t : 'Sidebar'|t }}">>

    There's a HTML syntax error here. Notice the 2 closing angle brackets (>>). This is repeated several times in the patch.

Re. #12:

2. classy will be removed from Drupal 9. So think there's no need to do the changes.

Classy hasn't been removed from D9, so the changes are needed there too. (It looks like Classy won't be removed until D10 now - see #3110137: Remove Classy from core and #2659890: [Policy] [Plan] Drupal 9 and 10 markup and CSS backwards compatibility).

sja112’s picture

Assigned: Unassigned » sja112
andrewmacpherson’s picture

Issue tags: +Needs change record

Any website which uses the stable or classy themes can automatically benefit from this change, but themes which have overridden the page template won't.

A change record would be good for this issue, to advise themers and distro maintainers to do something similar in their own page templates.

sja112’s picture

Assigned: sja112 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new14.22 KB
new1.93 KB

Hi @andrewmacpherson,

Thanks for the review of the patch. I have updated the patch to fix the issues mentiond above #32.

When I am trying to update the classy theme test case is failing with the error,

Drupal\KernelTests\Core\Theme\ConfirmClassyCopiesTest::testClassyHashes,

If a copied Classy asset is changed, it should no longer be in a /classy 
subdirectory. The files there should be exact copies from Classy. Once it has 
changed, it is custom to the theme and should be moved to a different 
location.
sja112’s picture

StatusFileSize
new13.18 KB
new1.93 KB

Hi @andrewmacpherson,

(Uploaded incorrect patch. re-adding the patch.)

Thanks for the review of the patch. I have updated the patch to fix the issues mentioned above #32.

When I am trying to update the classy theme test case is failing with the error,

Drupal\KernelTests\Core\Theme\ConfirmClassyCopiesTest::testClassyHashes,

If a copied Classy asset is changed, it should no longer be in a /classy 
subdirectory. The files there should be exact copies from Classy. Once it has 
changed, it is custom to the theme and should be moved to a different 
location.

So haven't added changes in classy theme.

andrewmacpherson’s picture

StatusFileSize
new8.04 KB
new17.25 KB

Thanks for working on this @sja112.

I looked at ConfirmClassyCopiesTest to see what we need to do, and I understand it now. Here's a summary of what it does:

  • The getClassyHash() helper method has a big list of MD5 checksums for all of the templates in the Classy theme. We're expecting to see these in the following tests.
  • The first test (testClassyHashes()) calculates the MD5 checksum for each template in the Classy theme, and confirms it is the expected value from the helper method. If we change a template from the Classy theme (for example maintenance-page.html.twig) then this test will fail.
  • The second test (testClassyCopies()) calculates the MD5 checksum for templates in other themes, which are supposed to be exact copies of the template in Classy. If we change the maintenance-page.html.twig template from Umami, this test will fail.
  • When both of these tests pass, it means the maintenance-page.html.twig templates in Classy and Umami are identical.

So, if we want to make changes to templates in Classy, we have to update the expected MD5 checksum stored in the ConfirmClassyCopiesTest::getClassyHash(), and make sure exactly the same changes are made to the Classy copies in the other core themes.

The affected templates are these ones. In this patch, I've updated the templates and the MD5 hashes stored in the test.

$ ack  -l --type=twig --sort-files "complementary" | grep classy
core/profiles/demo_umami/themes/umami/templates/classy/layout/maintenance-page.html.twig
core/themes/classy/templates/layout/maintenance-page.html.twig
core/themes/classy/templates/layout/page.html.twig
andrewmacpherson’s picture

StatusFileSize
new7.43 KB
new17.9 KB

I did some other remaining work. These page templates have 2 sidebars, but didn't have the conditional name check yet.

  • core/themes/claro/templates/install-page.html.twig
  • core/themes/seven/templates/install-page.html.twig
  • core/themes/stable/templates/layout/install-page.html.twig
  • core/themes/stable/templates/layout/maintenance-page.html.twig
  • core/themes/stable/templates/layout/page.html.twig
  • core/themes/stable9/templates/layout/install-page.html.twig
  • core/themes/stable9/templates/layout/maintenance-page.html.twig
  • core/themes/stable9/templates/layout/page.html.twig
andrewmacpherson’s picture

A good issue for the Accessibility Bug Bash during DrupalCon Global 2020.

carlygerard’s picture

@andrewmacpherson I can confirm #38 works in Bartik and Stark for sure. Not sure how to get the two sidebars to appear on the admin install pages to check those, but it's the same markup so I imagine it would work for Stable/Seven/Claro--being able to check would be good though.

andrewmacpherson’s picture

You get sidebars to appear by placing blocks in them. The templates check whether there is anything in the sidebar, before creating the HTML wrapper.

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.

pasqualle’s picture

Version: 9.2.x-dev » 9.1.x-dev
xjm’s picture

Version: 9.1.x-dev » 9.2.x-dev
Issue tags: -beta target

This was only a beta target for the 9.0.x beta, so fixing metadata. Beta targets for minor branches are different. Thanks!

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.

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.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new144 bytes

The Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

gauravvvv’s picture

Status: Needs work » Needs review
StatusFileSize
new9.65 KB

As stable and seven are no longer part of 10.1.X. Patch #38, no longer applies. I have added an updated patch. please review

smustgrave’s picture

Status: Needs review » Needs work

Was previously tagged for tests. Can probably do simple assertions

This seems tied to #2655794: Remove redundant WAI-ARIA role attributes from <main>, <nav>, <aside>, <header>, and <footer> elements so maybe they should be combined or least share a change record.

If kept separate think this one needs to get in first over #2655794: Remove redundant WAI-ARIA role attributes from <main>, <nav>, <aside>, <header>, and <footer> elements as that one removes redundant roles but aside tags would still be wrong until this lands.

mgifford’s picture

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.

kristen pol’s picture

I’m triaging for DrupalCon mentored contribution and reviewing as this issue is tagged novice.

*******
Please leave this issue for DrupalCon mentored contribution as a possible first time issue.

*******

The patch is simple and passes tests. Smustgrave noted maybe other issues should be considered at the same time as this but, even so, tests can be added to this patch.

This issue requires someone who knows how to code. They don’t necessarily need to know how to create tests and could be mentored on that.

kristen pol’s picture

Issue tags: +DrupalCon Pittsburgh 2023

Tagging

kristen pol’s picture

Issue tags: -DrupalCon Pittsburgh 2023 +Pittsburgh 2023

Fixing tag :)

kristen pol’s picture

Issue tags: -Pittsburgh 2023 +Pittsburgh2023

Tag normalization happening:)

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.