Problem/Motivation

The Admin Toolbar misuses the aria-owns attribute. This has resulted in a bug which makes links within the admin toolbar completely unusable, when using assistive tech which supports aria-owns.

The admin toolbar tray links are crucial for so many admin tasks, that this bug effectively prevents affected users from being able to use Drupal for anything much.

So far, only JAWS is known to be affected, but it applies in theory to any assistive tech which correctly processes aria-owns.

This bug can be reproduced:

  1. In Windows (this problem was not present in any OSX browser/voiceover)
  2. using either Internet Explorer or Firefox (Chrome does not have this problem)
  3. and with the JAWS screenreader enabled, version 2019 (other versions may be impacted as well, but this is the current version and definitely reproduces the issue)

In this scenario, links within the admin toolbar are unusable if activated using the keyboard when JAWS is running. Regardless of the link/button that is focused, the click event is routed to the toggle button.

The links do still work if clicked with a mouse pointer when JAWS is running (because JAWS doesn't intercept mouse clicks?). However this is NOT a feasible mitigation/workaround for many JAWS users.

This is a video of the bug occurring.

The cause of the issue is due to the Admin Toolbar tray buttons associated with trays inappropriately using aria-owns. Browsers and screenreader support for aria-owns has been gradual, and is likely the reason this was not an issue identified until recently. It was not an issue with JAWS 16 (the version which was current when D8.0.0 was released).

Proposed resolution

In this issue, remove aria-owns from the toolbar tray buttons so items in the Admin Toolbar are interactable for non-pointer users running JAWS The are no benefits in these buttons using aria-owns, so removing this attribute will only benefit users.

Remaining tasks

3 follow-up issues have been been created for improvements which are less urgent, as part of a plan to improve toolbar accessibility.

Backporting - This is a very important candidate for backporting. Ideally it will be included in an 8.7.z point release, before the 8.7 branch enters the security-only support phase.

User interface changes

Fixes a major barrier to using the toolbar with JAWS screen reader.
No changes to visual design or behaviour without assistive tech.

API changes

n/a

Data model changes

n/a

Release notes snippet

Fixed a major accessibility bug which prevented toolbar links from working with some screen readers. Websites which need to support administrators who use assistive technology are strongly recommended to upgrade. If in doubt, assume this is the case, particularly in larger organizations. Discussing the issue with staff from IT user-support, disabled employee support, and human resources teams is advisable.

Previous issue summary:

Steps to recreate: When using JAWS 2018/2019 (screen reader) with IE11. - Login to Drupal and try to access the admin toolbar.

Results: You can only select the toggle button. The links within on TAB reads the same toggle button title text (title="Admin menu"), but more critically you can only click the toggle button. So you cannot access any of the links within, making the CMS unusable for a user with a dependence on a screen reader in a work environment that has a JAWS and IE as standard.

Using tab and selecting the links without JAWS works fine. This is critical because users of the CMS will be using screen readers.

Remove the title (title="Admin menu") doesn't help. It reads the next bit of text available for all links.

<div class="toolbar-tab">
        <a href="/admin" title="Admin menu" class="toolbar-icon toolbar-icon-menu trigger toolbar-item is-active" data-drupal-subtrees="" id="toolbar-item-administration" data-toolbar-tray="toolbar-item-administration-tray" aria-owns="toolbar-item-administration-tray" role="button" aria-pressed="false" tabindex="-1">Manage</a>
        <div id="toolbar-item-administration-tray" data-toolbar-tray="toolbar-item-administration-tray" class="toolbar-tray toolbar-tray-horizontal is-active" data-offset-top=""><nav class="toolbar-lining clearfix" role="navigation" aria-label="Administration menu"><h3 class="toolbar-tray-name visually-hidden">Administration menu</h3><div class="toolbar-menu-administration"><ul class="toolbar-menu root"><li class="menu-item menu-item--collapsed level-1"><div class="toolbar-box"><a href="/admin/content" title="Find and manage content." id="toolbar-link-system-admin_content" class="toolbar-icon toolbar-icon-system-admin-content" data-drupal-link-system-path="admin/content" tabindex="-1">Content</a><button class="toolbar-icon toolbar-handle" tabindex="-1"><span class="action">Extend</span> <span class="label">Content</span></button></div>
              <ul class="toolbar-menu">
                    <li class="menu-item level-2">
        <div class="toolbar-box"><a href="/admin/content/comment" title="List and edit site comments and the comment approval queue." id="toolbar-link-comment-admin" class="toolbar-icon toolbar-icon-comment-admin" data-drupal-link-system-path="admin/content/comment">Comments</a></div>
              </li>
                <li class="menu-item level-2">
        <div class="toolbar-box"><a href="/admin/content/domain-content" title="Lists content by domain assignment." id="toolbar-link-domain_content-content_list" class="toolbar-icon toolbar-icon-domain-content-content-list" data-drupal-link-system-path="admin/content/domain-content">Affiliated content</a></div>
              </li>
                <li class="menu-item level-2">
        <div class="toolbar-box"><a href="/admin/content/domain-editors" title="Lists editors by domain assignment." id="toolbar-link-domain_content-editors_list" class="toolbar-icon toolbar-icon-domain-content-editors-list" data-drupal-link-system-path="admin/content/domain-editors">Affiliated editors</a></div>
              </li>
        </ul>
            

Comments

OBKev created an issue. See original summary.

andrewmacpherson’s picture

Component: theme system » toolbar.module
Priority: Critical » Major
Issue summary: View changes
Issue tags: -admin toolbar +Accessibility, +Needs accessibility review

Minor edit to the issue summary. Wrapping the specimen markup provided by @OBKev in code tags to make it clearer that it's specimen code.

andrewmacpherson’s picture

This report isn't very clear, but there are a few clues in the specimen markup:

  • The "admin menu" title refers to the "manage" button, which also has an unhelpful title attribute.
  • The "extend content" in the specimen markup - this is a clue that the user has the toolbar in vertical orientation, and the "manage" tray is open.
  • The "affiliated editors" and "affiliated content" links aren't from Drupal core. Most likely this site has some custom views listing pages, configured as primary local tasks (a.k.a. primary tabs). Those would end up in the menu as shown here.

The "toggle button" is in fact a HTML <a> with role="button". It responds to the return key, but not the spacebar key. This should be fixable, preferably by using <button>, or adding a keyboard handler for the space key. The expected behaviour of an element with the button role is that it can be activated by the spacebar key.

It also has the aria-pressed="false" property, but crucially the value of this does not change! Pressing the button repeatedly does actually cause the administration menu to be shown/hidden, but the button does not report any change in state. The administration menu links are revealed, and pressing tab would take you to them, but the fact that the button apparently does nothing is very confusing.

These problems are both fixable.

Aside: I've started an overall plan to deal with other accessibility issues with the toolbar module, at #3084529: [META] improve accessibility of toolbar.

andrewmacpherson’s picture

I had a chance to test this manually today. I experienced the same problem behaviour that OBKev reported, using Win10, JAWS 2019, and IE11. Also with Firefox/JAWS.

I also tried it with IE11/NVDA and Firefox/NVDA. In these cases I was able to access the links.

So, that's different behaviour with the same browsers, but different screen readers.

I noticed that our top-level tray buttons have an aria-owns relationship with the associated list of links. That's probably inappropriate. The purpose of aria-owns is to create a parent/child relationship. Basically it's saying: "these links are part of the button".

This would actually explain why each press of the TAB key repeats all the link names, and only the button can be operated. Visually, I could see the focus move to the next link in the toolbar. However each time I did this it announced the button text and the names of all the links in the associated second-level tray. What I think is happening is that the browser is responding to the TAB key correctly, and advances to the next focusable link. But these links are interpreted by JAWS as children of the button. So as far as JAWS is concerned, the button is still the active control. Pressing enter/space activates the button, not the link. The reason all the links are read out is that these are children of the button, so they form part of it's name. It's a button with a really long name.

That's my current theory anyway. Next: I'll remove the aria-owns relationship property, and see if that makes a difference.

I looked for information about support for aria-owns, but I couldn't find much. I'll keep looking.

FWIW, I frequently use NVDA to operate Drupal, but seldom use JAWS. Since I'm sighted, I often navigate to the page I want, then turn the screen reader on to check the particular thing I'm interested in testing. This may explain why I've never run into this before.

Aside: the issues I noted in comment #3 are red herrings here (most likely) but are still worth fixing anyway. I'll make separate issues for those.

andrewmacpherson’s picture

Created separate issues for the problems described in comment #3.

andrewmacpherson’s picture

Status: Active » Needs review
Issue tags: +Needs manual testing
StatusFileSize
new568 bytes

This patch removes the aria-owns from the toolbar button. It should stop the links being treated as children of the button.

andrewmacpherson’s picture

Success! I spent some hours testing the patch in comment #6. It solves the problem as expected.

More detail:

The bug report was about the latest JAWS (v2019, presumably) and IE11. In comment #4, I replicated the problem. Using JAWS 2019 with IE11 means that all the links in a toolbar tray can't be activated. They can be tabbed to, but they pressing enter activates the parent button. This was also the case with JAWS 2019 and Firefox. Although Firefox doesn't work so well with JAWS 2019, I was still able to determine that the behaviour affected it, using the visible screen reader cursor.

With the patch from #6, removing aria-owns, the problem behaviour went away. Using JAWS 2019 with IE11, I could activate the individual links in a toolbar tray, such as content, appearance, extend, etc. Also confirmed this in Firefox.

I did some more testing of various scenarios of different toolbar trays, and using the toolbar tray in vertical orientation. All are working with JAWS 2019 after patch #6.

I was sure the toolbar had worked correctly in the past, so I dug out an old software version: JAWS 16, which dates from 2014, before the release of Drupal 8.0.0. The toolbar tray links WERE accessible using JAWS 16 with IE11, before and after the patch in comment #6.

During testing I made sure to perform a Drupal cache-rebuild (via drush cr) and inspect the DOM in IE11 dev tools, to confirm the presence or absence of the aria-owns attribute.

I did some testing with NVDA (a 2019 version) with Firefox and IE11. There is no difference before or after the patch.

Conclusions:
Our use of aria-owns is inappropriate. The ARIA rec clearly states that this is intended to create a parent/child relationship between elements, which is not our intention. The attribute is really intended for situations where you need to fake a relationship like unordered-list/list-item. The relationship was set up by #2471809: Toolbar module does not follow W3C in May 2015, during the D8.0 beta period. I believe @jessebeach got this wrong, but the problem went unnoticed at the time. There's no mention of any manual screen reader testing in that patch.
Support for aria-owns among browsers and AT has been poor in the past. This would explain why the bug wasn't observed earlier. We were using the attribute in the wrong way, but it didn't matter because it had no effect anyway.
JAWS has gained support for the aria-owns attribute, at some point between version 16 and version 2019. Release notes are available, so perhaps the answer can be found there.

The button/tray relationship we actually want to use is aria-controls. We can also replace aria-pressed with aria-expanded as the correct way to indicate a disclosure behaviour. I've noted this in the parent toolbar accessibility plan already.

I propose:

  1. Remove aria-owns from the toolbar tray buttons as a matter of urgency. Treat this as a high priority for backporting, ideally before the 8.7.x branch moves to security-fixes only.
  2. Implement aria-controls and aria-expanded for the toolbar tray buttons in a follow up issue, with FunctionalJavascript tests.
andrewmacpherson’s picture

Still TODO:

  • It will be a good idea to do some before/after manual testing of patch #6 with other browser/screen reader combinations.
  • Update the issue summary, so that it's easier for committers to understand the problem.
  • Check other issues arising from here have their own follow-up issues under the parent toolbar accessibility plan. Replacing aria-pressed with aria-expanded + aria-controls still needs filing I think.
andrewmacpherson’s picture

Title: Admin toolbar not usable with latest versions of JAWS » Admin toolbar not usable with latest versions of JAWS due to mis-use of aria-owns
wim leers’s picture

On JAWS

🤔It sounds like this is only a problem in the later versions of JAWS, i.e. it worked okay a few years ago? But perhaps it only worked by accident in the past?

Ah, yes, that's exactly it! @andrewmacpherson confirmed this hypothesis in his research in #7:

Support for aria-owns among browsers and AT has been poor in the past. This would explain why the bug wasn't observed earlier. We were using the attribute in the wrong way, but it didn't matter because it had no effect anyway.
JAWS has gained support for the aria-owns attribute, at some point between version 16 and version 2019. Release notes are available, so perhaps the answer can be found there.

On aria-owns

First of all: thanks for the lovely detective work to trace this back to #2471809: Toolbar module does not follow W3C! 🙏

The ARIA rec clearly states that this is intended to create a parent/child relationship between elements, which is not our intention.

It … kind of is? Some toolbar buttons own a tray. Triggering a button opens the tray. This is the parent-child relationship. But

On plan of action

The end of #7 proposes to make this issue fix the AT-show-stopping bug and add the correct ARIA attributes in a follow-up issue. I think that makes sense.

bnjmnm’s picture

Issue summary: View changes
bnjmnm’s picture

Status: Needs review » Reviewed & tested by the community

I manually reviewed the patch in #6. The problem was completely fixed with the two browsers this bug was occurring in: Firefox and IE11.
The successful fix can be seen in IE11 in this video.

As a precaution, I also tested these previously-working combinations to make sure the removal of aria-owns had no adverse effects.
Windows+Chrome+JAWS
Windows+(IE11, Firefox, Chrome)+NVDA
OSX+(Chrome, Firefox, Safari, Opera)+Voiceover

This still needs a followup issue and a change record, but I'm setting this to RTBC now to keep the momentum going on this issue. Ideally I'll have these additional steps completed before any additional review takes place.

wim leers’s picture

Thanks for the manual testing and issue summary update, @bnjmnm!

andrewmacpherson’s picture

Thanks for reviewing this!

#10:

It … kind of is? Some toolbar buttons own a tray. Triggering a button opens the tray. This is the parent-child relationship. But

That's not what aria-owns means. It means parent > child in the same way as ul > li.

In toolbar, there is a button followed by a series of links. But with aria-owns, we're telling (i.e. lying to) JAWS that there is a button containing a series of links: button > a

The links are still tab stops. However a button cannot have interactive child elements. So activating a link inside a button is activating the button.

andrewmacpherson’s picture

Just want to add that this needs a high-priority for back-porting. It would be great if it goes into an 8.7.z patch release before the 8.7 branch enters the security-only phase.

bnjmnm’s picture

Added CR and followup #3090120: Improve accessibility semantics for Toolbar buttons with trays
For the CR, the Branch/Versions are both in 8.9, but I agree with @andrewmacpherson that this should get backported as far as possible. I'm not sure how that might impact the versions in the CR.

wim leers’s picture

#14: thanks for clarifying, that helps a lot, and I'm sure it'll also help committers! 👍

andrewmacpherson’s picture

Issue summary: View changes

Clarified some stuff in the summary. It only affects AT users where the AT supports aria-owns, which isn't the same as all non-pointer users. A keyboard user, without a screen reader, can still operate the links inside toolbar trays

The change record looks good, thanks @bnjmnm.

Everything is done here. The issue scope is narrowed to the very urgent removal of aria-owns. Meanwhile 3 further improvements have their own issues as part of a parent plan.

andrewmacpherson’s picture

andrewmacpherson’s picture

Issue summary: View changes

Updated the release notes snippet. The mechanics of this issue are somewhat esoteric, so I changed it to something more helpful to site owners who don't know whether it affects them. Meanwhile, the change record provides the technical summary.

alexpott’s picture

Version: 8.7.x-dev » 8.8.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed and pushed 81c058aa0a to 9.0.x and a6f060af0d to 8.9.x. Thanks!

Going to get +1 for 8.8.x backport. Also I'm not convinced that a CR is necessary here. Markup is not covered by our BC promise. WIll ask a release manager.

Credited @Wim Leers for reviews and @OBKev for filing the issue.

  • alexpott committed 81c058a on 9.0.x
    Issue #3066954 by andrewmacpherson, Wim Leers, bnjmnm, OBKev: Admin...

  • alexpott committed a6f060a on 8.9.x
    Issue #3066954 by andrewmacpherson, Wim Leers, bnjmnm, OBKev: Admin...
alexpott’s picture

Status: Patch (to be ported) » Fixed

Discussed with @catch and we agreed to backport and that the CR is not necessary - so I've not published it. If other agree please delete - otherwise let's discuss more.

  • alexpott committed 21e841c on 8.8.x
    Issue #3066954 by andrewmacpherson, Wim Leers, bnjmnm, OBKev: Admin...
andrewmacpherson’s picture

Version: 8.8.x-dev » 8.7.x-dev
Status: Fixed » Patch (to be ported)

Can this one go in the next 8.7.x patch release window? It's a major bug fix, and non-disruptive.

It prevents some users from navigating the admin pages at all, and I'm struggling to think of feasible workarounds.

alexpott’s picture

Status: Patch (to be ported) » Fixed

Discussed with @catch and we agreed to backport to 8.7.x

  • alexpott committed b465b2f on 8.7.x
    Issue #3066954 by andrewmacpherson, Wim Leers, bnjmnm, OBKev: Admin...
andrewmacpherson’s picture

Awesome! Thanks to everyone who worked on this.

I think it might count as the single biggest impact a11y fix since D8.0.0, so it's great to have this in all the supported D8 branches.

wim leers’s picture

I think it might count as the single biggest impact a11y fix since D8.0.0, so it's great to have this in all the supported D8 branches.

Wow!

andrewmacpherson’s picture

Per #24, I went to delete the draft change record. I don't see a delete button though; does this require a permission I don't have? The CR is unpublished, so it's no big deal.

wim leers’s picture

#31 Indeed, that requires the "webmaster" role. I deleted it for you :)

xjm’s picture

Priority: Major » Critical
Issue tags: +8.7.9 release notes

Based on the discussion above and the IS I'm actually raising this to critical. Not being able to use the admin toolbar at all means the site was basically unusable for everyone using JAWS.

We highlight critiical bug fixes in the release notes. I am also going to belatedly highlight this in the 8.7.9 release notes too.

Great work!

andrewmacpherson’s picture

@xjm - good call. There's a release notes snippet here, you could use.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.