@lgeggleston
Submitted on behalf of University of Virginia (UVA) Library’s Assessment, Communications, and User Experience (ACE) team as part of internal DSpace 9 accessibility audit.
Issue 1 of 4: 3 Dot Menu Screen Reader Issue
Describe the bug
When using a screen reader, the expanded options within the 3 dot menu are not accessible. The screen reader is able to read the menu name and expand the dropdown, but it does not recognize either list item (subscribe, edit this community). Screen reader users are not able to perceive nor interact with these expanded options.
Page
Community and Collections Browse and Search
WCAG Guideline
WCAG 2.1.1, 2.4.3, 4.1.2
To Reproduce
Relevant code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c294351535="" class="ng-tns-c294351535-13" \_nghost-dspace-angular-c2948902503=""\>\<div \_ngcontent-dspace-angular-c2948902503="" role="menubar" class="dso-edit-menu d-flex"\>\<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted" style=""\>\<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\>
Expected behavior
This is happening due to misuse of ARIA roles, as well as using an empty href where there should be a button. Additionally, we can remove role="presentation" so that users can hear how many list items there are to reduce cognitive load for screen reader users.
Summary of Changes
Remove:
- role="menubar" from the outer <div class="dso-edit-menu d-flex">
- role="menuitem" from the <button ngbdropdowntoggle>
- role="menu" from the <ul ngbdropdownmenu>
- role="presentation" from all <li> elements
- role="menuitem" from all <a> elements
Change:
Modal trigger ("Subscribe") — from <a href="javascript:void(0);"> to <button type="button" aria-haspopup="dialog">
Keep:
aria-expanded on the toggle button <a href="..."> for "Edit this community" (navigates to a real URL) aria-hidden="true" on decorative icons tabindex="0" on the toggle button (note: technically redundant on a <button> since buttons are natively focusable)
Suggested fix / example code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c294351535="" class="ng-tns-c294351535-13" \_nghost-dspace-angular-c2948902503=""\> \<div \_ngcontent-dspace-angular-c2948902503="" class="dso-edit-menu d-flex"\> \<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted" style=""\> \<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\> \<div \_ngcontent-dspace-angular-c2003421933="" ngbdropdown="" container="body" placement="bottom-right" class="dso-button-menu mb-1 ng-star-inserted dropdown"\> \<div \_ngcontent-dspace-angular-c2003421933="" container="body" class="d-flex flex-row flex-nowrap"\> \<button \_ngcontent-dspace-angular-c2003421933="" ngbdropdowntoggle="" tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\> \<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\> \<ul \_ngcontent-dspace-angular-c2003421933="" ngbdropdownmenu="" class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\> \<li \_ngcontent-dspace-angular-c2003421933="" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\> \<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\> \<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-bell fa-fw fas ng-star-inserted"\>\</i\>\</div\> \<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\> \<button \_ngcontent-dspace-angular-c580104809="" type="button" aria-haspopup="dialog" class="ds-menu-item ng-star-inserted" data-test="subscriptions.tooltip"\>Subscribe\</button\>\</ds-onclick-menu-item\>\</li\> \<li \_ngcontent-dspace-angular-c2003421933="" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\> \<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\> \<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-fw fa-pencil-alt fas ng-star-inserted"\>\</i\>\</div\> \<ds-link-menu-item \_nghost-dspace-angular-c721316482="" class="ng-star-inserted"\> \<a \_ngcontent-dspace-angular-c721316482="" href="/communities/79bbdb80-47a6-43c0-bb54-5816da366316/edit/metadata" tabindex="0" class="ds-menu-item" data-test="link-menu-item.community.page.edit"\>Edit this community\</a\> \</ds-link-menu-item\>\</li\>\</ul\>\</div\>\</ds-dso-edit-menu-expandable-section\>\</div\>\</div\>\</ds-dso-edit-menu\>
Issue 2 of 4: Screen Reader Key Commands - Keyboard Navigation
Describe the bug
Two issues for the same code:
- Screen reader is jumping from menu to full window and repeating page title multiple times before jumping back to menu and misses items.
- Voice Over keyboard commands aren't working on main navigation properly. Have to press "Enter" or "space" instead of VO+enter or VO+space.
The current usage of aria messes up navigation for screen reader -- application type of navigation instead of web browser type of navigation. ARIA "menu" and "menuitem" are only appropriate for desktop‑style application menus, not site navigation. Markup is currently forcing VoiceOver into application‑menu mode, which is why VO+Space (Screen Reader Keyboard Operations) doesn’t activate anything and most likely why the screen reader is jumping to the main window (the application type of menu makes Voice Over behave differently). There could be other issues causing the screen reader to jump, but this is most likely. Will need to recheck after the code is updated to ensure there's no other issue causing the jumping.
Page
Home
WCAG Guideline
WCAG 2.1.1, 1.3.1, and 4.1.2
To Reproduce
Relevant code
\<div \_ngcontent-dspace-angular-c2264348223="" id="main-site-header-container" class="container h-100 d-flex flex-row align-items-center justify-content-between gapx-3 gapy-2"\>\<div \_ngcontent-dspace-angular-c2264348223="" id="header-left" class="h-100 flex-fill d-flex flex-row flex-nowrap justify-content-start align-items-center gapx-3 flex-grow-1" role="presentation"\>\<a \_ngcontent-dspace-angular-c2264348223="" routerlink="/home" role="button" tabindex="0" class="d-block my-2 my-md-0" aria-label="Home" href="/home"\>\<img \_ngcontent-dspace-angular-c2264348223="" id="header-logo" src="assets/libraopen/images/library\_logo-web.svg" alt="Repository logo"\>\</a\>\<nav \_ngcontent-dspace-angular-c2264348223="" id="desktop-navbar" class="navbar navbar-expand p-0 align-items-stretch align-self-stretch flex-grow-1 flex-shrink-1 ng-star-inserted" aria-label="Main navigation bar" style=""\>\<ds-navbar \_ngcontent-dspace-angular-c2264348223="" data-used-theme="libraopen"\>\<ds-themed-navbar \_nghost-dspace-angular-c2580205027="" class="ng-tns-c2580205027-13 ng-star-inserted"\>\<!----\>
Expected behavior
Remove instances of: role="menubar", role="menu", role="menuitem", aria-haspopup="menu". These were forcing VoiceOver into application‑menu mode, which is why VO+Space didn’t activate links.Remove all role="presentation". The <div>s are already presentational, so these attributes are redundant.
Remove all tabindex="0" from <a href> because links are inherently focusable. The tabindex only compensates for the broken ARIA.
Add minimal ARIA only to the dropdown toggle. Because the toggle is not a <button>, give it the role="button", tabindex="0", aria-expanded, aria-controls. Edits should both restore native keyboard + screen reader behavior. So tab moves between links, enter activates, VO+Space activates, VO+Enter activates, and Dropdown toggle works with Space, Enter, VO+Space. Use <nav> or role="navigation" instead – menu is only used for like system desktop applications, not for web browsers.
Please note that this will require updating the JS query selectors since they currrently reference the role=menuitem in the "expandablenavbarsectionID". It looked like "inExpandableNavbar" might also need to be double checked, but I didn't dive too deep into that one. Please just review to avoid referencing a role that no longer is used.
Suggested fix / example code
\<nav aria-label="Main navigation" class="navbar"\> \<div class="navbar-nav"\> \<!-- ========================= --\> \<!-- SIMPLE LINK (NOT DROPDOWN) --\> \<!-- ========================= --\> \<div class="ds-menu-item-wrapper"\> \<a href="/community-list" class="ds-menu-item"\>Communities & Collections\</a\>\</div\> \<!-- ========================= --\> \<!-- DROPDOWN SECTION --\> \<!-- ========================= --\> \<div class="ds-menu-item-wrapper"\> \<!-- DROPDOWN TOGGLER --\> \<!-- This is NOT a \<button\>, so we add minimal ARIA --\> \<div class="ds-menu-toggler-wrapper" role="button" tabindex="0" aria-expanded="false" aria-controls="all-of-libraopen-dropdown"\> \<span class="ds-menu-item"\>All of LibraOpen\</span\> \<i class="fas fa-caret-down fa-xs"\>\</i\>\</div\> \<!-- DROPDOWN PANEL --\> \<!-- No role="menu" — this is just a list of links --\> \<div id="all-of-libraopen-dropdown" class="dropdown-menu" hidden\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/dateissued" class="ds-menu-item"\> By Publication Date\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/author" class="ds-menu-item"\> By Author\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/title" class="ds-menu-item"\> By Title\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/subject" class="ds-menu-item"\> By Subject\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/srsc" class="ds-menu-item"\> By Subject Category\</a\>\</div\>\</div\>\</div\> \<!-- ========================= --\> \<!-- SIMPLE LINK (NOT DROPDOWN) --\> \<!-- ========================= --\> \<div class="ds-menu-item-wrapper"\> \<a href="/statistics" class="ds-menu-item"\> Statistics\</a\>\</div\>\</div\>\</nav\>
JAVA SCRIPT
When you remove role="menuitem" from the dropdown items in the markup (to simplify ARIA usage), you will need to update the JavaScript selectors accordingly. The current JS uses selectors like [role="menuitem"] to find and manage keyboard focus on dropdown items. To maintain keyboard accessibility, replace these selectors with ones matching your updated markup, such as a class selector (e.g., .ds-menu-item) or another attribute.
Issue 3 of 4: Skipping Edit Menu
Describe the bug
Screen Reader VoiceOver (VO) skips the 3 dot edit menu entirely when reading through the page. It jumps focus from the H1 header to the window and then to the thumbnail. The edit menu is not accessible through the reader unless they manually key through the page.
Page
Item Page
WCAG Guideline
WCAG 1.3.1, 4.1.2, 2.1.1, 2.1.2
To Reproduce
Relevant code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c3947076920="" \_nghost-dspace-angular-c2948902503=""\>\<div \_ngcontent-dspace-angular-c2948902503="" role="menubar" class="dso-edit-menu d-flex"\>\<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted"\>\<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" ngbdropdown="" container="body" placement="bottom-right" class="dso-button-menu mb-1 ng-star-inserted dropdown"\>\<div \_ngcontent-dspace-angular-c2003421933="" container="body" class="d-flex flex-row flex-nowrap"\>\<button \_ngcontent-dspace-angular-c2003421933="" ngbdropdowntoggle="" role="menuitem" tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i \_ngcontent-dspace-angular-c2003421933="" class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<!----\>\<ul \_ngcontent-dspace-angular-c2003421933="" ngbdropdownmenu="" role="menu" class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-fw fa-pencil-alt fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-link-menu-item \_nghost-dspace-angular-c721316482="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c721316482="" role="menuitem" href="/entities/publication/08806560-a17a-4774-b063-d901b1335d70/edit/metadata" tabindex="0" class="ds-menu-item" data-test="link-menu-item.publication.page.edit"\>Edit this item\</a\>\</ds-link-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-eye-slash fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Request a withdrawal for this item" data-test="item.page.withdrawn"\>Request a withdrawal for this item\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-code-branch fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Create new version" data-test="item.page.version.create"\>Create new version\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<!----\>\</ul\>\</div\>\<!----\>\</ds-dso-edit-menu-expandable-section\>\<!----\>\</div\>\<!----\>\</div\>\</ds-dso-edit-menu\>
Expected behavior
This is likely because of poor ARIA usage which makes VO interpret role=menubar as an instruction to jump back to the window menu. When the user does key to the edit menu, they are able to open it, but they can't key into the menu itself and go through the options. The VO commands do not work, and this is also because of the ARIA menu role, which makes screen readers behave differently. A contributing factor can also be that the menu items have role=presentation in the <li> attribute and then include an <a>, but the role=presentation is not necessary and conflicts with <a>.
Summary of Changes
REMOVE:
- role="menubar" from the outer <div class="dso-edit-menu d-flex">
- role="menuitem" from the <button ngbdropdowntoggle>
- role="menu" from the <ul ngbdropdownmenu>
- role="presentation" from all <li> elements
- role="menuitem" from all <a> elements
CHANGE:
Modal triggers ("Request a withdrawal" and "Create new version"):
From: <a href="javascript:void(0);">
To: <button type="button" aria-haspopup="dialog">
KEEP
- aria-expanded on the toggle button (critical for announcing dropdown state)
- <a href="..."> for "Edit this item" (it navigates to a new page)
- aria-hidden="true" on decorative icons
Suggested fix / example code
\<ds-dso-edit-menu\>\<div class="dso-edit-menu d-flex"\>\<div class="ms-1"\>\<ds-dso-edit-menu-expandable-section\>\<div ngbdropdown container="body" placement="bottom-right" class="dso-button-menu mb-1 dropdown"\>\<div container="body" class="d-flex flex-row flex-nowrap"\>\<button ngbdropdowntoggle tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<ul ngbdropdownmenu class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-fw fa-pencil-alt fas"\>\</i\>\</div\>\<ds-link-menu-item\>\<a href="/entities/publication/08806560.../edit/metadata" tabindex="0" class="ds-menu-item"\>Edit this item\</a\>\</ds-link-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-eye-slash fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Request a withdrawal for this item"\>Request a withdrawal for this item\</button\>\</ds-onclick-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-code-branch fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Create new version"\>Create new version\</button\>\</ds-onclick-menu-item\>\</li\>\</ul\>\</div\>\</ds-dso-edit-menu-expandable-section\>\</div\>\</div\>\</ds-dso-edit-menu\>
Issue 4 of 4: Broken Edit Menu Navigation
Describe the bug
When keying, the 3 dot edit menu options do not respond to the VoiceOver key command (VO+space), but it will respond to "space" alone. This is also a keyboard violation as screen reader users are unable to use the standard keying that should automatically work.
Page
Item Page
WCAG Guideline
WCAG 1.3.1, 4.1.2, 2.1.1, 2.1.2
To Reproduce
Relevant code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c3947076920="" \_nghost-dspace-angular-c2948902503=""\>\<div \_ngcontent-dspace-angular-c2948902503="" role="menubar" class="dso-edit-menu d-flex"\>\<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted"\>\<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" ngbdropdown="" container="body" placement="bottom-right" class="dso-button-menu mb-1 ng-star-inserted dropdown"\>\<div \_ngcontent-dspace-angular-c2003421933="" container="body" class="d-flex flex-row flex-nowrap"\>\<button \_ngcontent-dspace-angular-c2003421933="" ngbdropdowntoggle="" role="menuitem" tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i \_ngcontent-dspace-angular-c2003421933="" class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<!----\>\<ul \_ngcontent-dspace-angular-c2003421933="" ngbdropdownmenu="" role="menu" class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-fw fa-pencil-alt fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-link-menu-item \_nghost-dspace-angular-c721316482="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c721316482="" role="menuitem" href="/entities/publication/08806560-a17a-4774-b063-d901b1335d70/edit/metadata" tabindex="0" class="ds-menu-item" data-test="link-menu-item.publication.page.edit"\>Edit this item\</a\>\</ds-link-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-eye-slash fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Request a withdrawal for this item" data-test="item.page.withdrawn"\>Request a withdrawal for this item\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-code-branch fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Create new version" data-test="item.page.version.create"\>Create new version\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<!----\>\</ul\>\</div\>\<!----\>\</ds-dso-edit-menu-expandable-section\>\<!----\>\</div\>\<!----\>\</div\>\</ds-dso-edit-menu\>
Expected behavior
This is likely because of poor ARIA usage which makes VO interpret role=menubar as an instruction to jump back to the window menu. When the user does key to the edit menu, they are able to open it, but they can't key into the menu itself and go through the options. The VO commands do not work, and this is also because of the ARIA menu role, which makes screen readers behave differently. A contributing factor can also be that the menu items have role=presentation in the <li> attribute and then include an <a>, but the role=presentation is not necessary and conflicts with <a>. Summary of Changes
REMOVE
- role="menubar" from the outer <div class="dso-edit-menu d-flex">
- role="menuitem" from the <button ngbdropdowntoggle>
- role="menu" from the <ul ngbdropdownmenu>
- role="presentation" from all <li> elements • role="menuitem" from all <a> elements
CHANGE
Modal triggers ("Request a withdrawal" and "Create new version"):
From: <a href="javascript:void(0);">
To: <button type="button" aria-haspopup="dialog">
KEEP
- aria-expanded on the toggle button (critical for announcing dropdown state)
- <a href="..."> for "Edit this item" (it navigates to a new page)
- aria-hidden="true" on decorative icons
Suggested fix / example code
\<ds-dso-edit-menu\>\<div class="dso-edit-menu d-flex"\>\<div class="ms-1"\>\<ds-dso-edit-menu-expandable-section\>\<div ngbdropdown container="body" placement="bottom-right" class="dso-button-menu mb-1 dropdown"\>\<div container="body" class="d-flex flex-row flex-nowrap"\>\<button ngbdropdowntoggle tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<ul ngbdropdownmenu class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-fw fa-pencil-alt fas"\>\</i\>\</div\>\<ds-link-menu-item\>\<a href="/entities/publication/08806560.../edit/metadata" tabindex="0" class="ds-menu-item"\>Edit this item\</a\>\</ds-link-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-eye-slash fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Request a withdrawal for this item"\>Request a withdrawal for this item\</button\>\</ds-onclick-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-code-branch fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Create new version"\>Create new version\</button\>\</ds-onclick-menu-item\>\</li\>\</ul\>\</div\>\</ds-dso-edit-menu-expandable-section\>\</div\>\</div\>\</ds-dso-edit-menu\>
Related work
#5639
@lgeggleston
Submitted on behalf of University of Virginia (UVA) Library’s Assessment, Communications, and User Experience (ACE) team as part of internal DSpace 9 accessibility audit.
Issue 1 of 4: 3 Dot Menu Screen Reader Issue
Describe the bug
When using a screen reader, the expanded options within the 3 dot menu are not accessible. The screen reader is able to read the menu name and expand the dropdown, but it does not recognize either list item (subscribe, edit this community). Screen reader users are not able to perceive nor interact with these expanded options.
Page
Community and Collections Browse and Search
WCAG Guideline
WCAG 2.1.1, 2.4.3, 4.1.2
To Reproduce
Relevant code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c294351535="" class="ng-tns-c294351535-13" \_nghost-dspace-angular-c2948902503=""\>\<div \_ngcontent-dspace-angular-c2948902503="" role="menubar" class="dso-edit-menu d-flex"\>\<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted" style=""\>\<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\>Expected behavior
This is happening due to misuse of ARIA roles, as well as using an empty href where there should be a button. Additionally, we can remove role="presentation" so that users can hear how many list items there are to reduce cognitive load for screen reader users.
Summary of Changes
Remove:
Change:
Modal trigger ("Subscribe") — from <a href="javascript:void(0);"> to <button type="button" aria-haspopup="dialog">
Keep:
aria-expanded on the toggle button <a href="..."> for "Edit this community" (navigates to a real URL) aria-hidden="true" on decorative icons tabindex="0" on the toggle button (note: technically redundant on a <button> since buttons are natively focusable)
Suggested fix / example code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c294351535="" class="ng-tns-c294351535-13" \_nghost-dspace-angular-c2948902503=""\> \<div \_ngcontent-dspace-angular-c2948902503="" class="dso-edit-menu d-flex"\> \<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted" style=""\> \<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\> \<div \_ngcontent-dspace-angular-c2003421933="" ngbdropdown="" container="body" placement="bottom-right" class="dso-button-menu mb-1 ng-star-inserted dropdown"\> \<div \_ngcontent-dspace-angular-c2003421933="" container="body" class="d-flex flex-row flex-nowrap"\> \<button \_ngcontent-dspace-angular-c2003421933="" ngbdropdowntoggle="" tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\> \<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\> \<ul \_ngcontent-dspace-angular-c2003421933="" ngbdropdownmenu="" class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\> \<li \_ngcontent-dspace-angular-c2003421933="" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\> \<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\> \<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-bell fa-fw fas ng-star-inserted"\>\</i\>\</div\> \<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\> \<button \_ngcontent-dspace-angular-c580104809="" type="button" aria-haspopup="dialog" class="ds-menu-item ng-star-inserted" data-test="subscriptions.tooltip"\>Subscribe\</button\>\</ds-onclick-menu-item\>\</li\> \<li \_ngcontent-dspace-angular-c2003421933="" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\> \<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\> \<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-fw fa-pencil-alt fas ng-star-inserted"\>\</i\>\</div\> \<ds-link-menu-item \_nghost-dspace-angular-c721316482="" class="ng-star-inserted"\> \<a \_ngcontent-dspace-angular-c721316482="" href="/communities/79bbdb80-47a6-43c0-bb54-5816da366316/edit/metadata" tabindex="0" class="ds-menu-item" data-test="link-menu-item.community.page.edit"\>Edit this community\</a\> \</ds-link-menu-item\>\</li\>\</ul\>\</div\>\</ds-dso-edit-menu-expandable-section\>\</div\>\</div\>\</ds-dso-edit-menu\>Issue 2 of 4: Screen Reader Key Commands - Keyboard Navigation
Describe the bug
Two issues for the same code:
The current usage of aria messes up navigation for screen reader -- application type of navigation instead of web browser type of navigation. ARIA "menu" and "menuitem" are only appropriate for desktop‑style application menus, not site navigation. Markup is currently forcing VoiceOver into application‑menu mode, which is why VO+Space (Screen Reader Keyboard Operations) doesn’t activate anything and most likely why the screen reader is jumping to the main window (the application type of menu makes Voice Over behave differently). There could be other issues causing the screen reader to jump, but this is most likely. Will need to recheck after the code is updated to ensure there's no other issue causing the jumping.
Page
Home
WCAG Guideline
WCAG 2.1.1, 1.3.1, and 4.1.2
To Reproduce
Relevant code
\<div \_ngcontent-dspace-angular-c2264348223="" id="main-site-header-container" class="container h-100 d-flex flex-row align-items-center justify-content-between gapx-3 gapy-2"\>\<div \_ngcontent-dspace-angular-c2264348223="" id="header-left" class="h-100 flex-fill d-flex flex-row flex-nowrap justify-content-start align-items-center gapx-3 flex-grow-1" role="presentation"\>\<a \_ngcontent-dspace-angular-c2264348223="" routerlink="/home" role="button" tabindex="0" class="d-block my-2 my-md-0" aria-label="Home" href="/home"\>\<img \_ngcontent-dspace-angular-c2264348223="" id="header-logo" src="assets/libraopen/images/library\_logo-web.svg" alt="Repository logo"\>\</a\>\<nav \_ngcontent-dspace-angular-c2264348223="" id="desktop-navbar" class="navbar navbar-expand p-0 align-items-stretch align-self-stretch flex-grow-1 flex-shrink-1 ng-star-inserted" aria-label="Main navigation bar" style=""\>\<ds-navbar \_ngcontent-dspace-angular-c2264348223="" data-used-theme="libraopen"\>\<ds-themed-navbar \_nghost-dspace-angular-c2580205027="" class="ng-tns-c2580205027-13 ng-star-inserted"\>\<!----\>Expected behavior
Remove instances of: role="menubar", role="menu", role="menuitem", aria-haspopup="menu". These were forcing VoiceOver into application‑menu mode, which is why VO+Space didn’t activate links.Remove all role="presentation". The <div>s are already presentational, so these attributes are redundant.
Remove all tabindex="0" from <a href> because links are inherently focusable. The tabindex only compensates for the broken ARIA.
Add minimal ARIA only to the dropdown toggle. Because the toggle is not a <button>, give it the role="button", tabindex="0", aria-expanded, aria-controls. Edits should both restore native keyboard + screen reader behavior. So tab moves between links, enter activates, VO+Space activates, VO+Enter activates, and Dropdown toggle works with Space, Enter, VO+Space. Use <nav> or role="navigation" instead – menu is only used for like system desktop applications, not for web browsers.
Please note that this will require updating the JS query selectors since they currrently reference the role=menuitem in the "expandablenavbarsectionID". It looked like "inExpandableNavbar" might also need to be double checked, but I didn't dive too deep into that one. Please just review to avoid referencing a role that no longer is used.
Suggested fix / example code
\<nav aria-label="Main navigation" class="navbar"\> \<div class="navbar-nav"\> \<!-- ========================= --\> \<!-- SIMPLE LINK (NOT DROPDOWN) --\> \<!-- ========================= --\> \<div class="ds-menu-item-wrapper"\> \<a href="/community-list" class="ds-menu-item"\>Communities & Collections\</a\>\</div\> \<!-- ========================= --\> \<!-- DROPDOWN SECTION --\> \<!-- ========================= --\> \<div class="ds-menu-item-wrapper"\> \<!-- DROPDOWN TOGGLER --\> \<!-- This is NOT a \<button\>, so we add minimal ARIA --\> \<div class="ds-menu-toggler-wrapper" role="button" tabindex="0" aria-expanded="false" aria-controls="all-of-libraopen-dropdown"\> \<span class="ds-menu-item"\>All of LibraOpen\</span\> \<i class="fas fa-caret-down fa-xs"\>\</i\>\</div\> \<!-- DROPDOWN PANEL --\> \<!-- No role="menu" — this is just a list of links --\> \<div id="all-of-libraopen-dropdown" class="dropdown-menu" hidden\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/dateissued" class="ds-menu-item"\> By Publication Date\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/author" class="ds-menu-item"\> By Author\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/title" class="ds-menu-item"\> By Title\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/subject" class="ds-menu-item"\> By Subject\</a\>\</div\> \<!-- DROPDOWN LINK --\> \<div class="ds-menu-item-wrapper"\> \<a href="/browse/srsc" class="ds-menu-item"\> By Subject Category\</a\>\</div\>\</div\>\</div\> \<!-- ========================= --\> \<!-- SIMPLE LINK (NOT DROPDOWN) --\> \<!-- ========================= --\> \<div class="ds-menu-item-wrapper"\> \<a href="/statistics" class="ds-menu-item"\> Statistics\</a\>\</div\>\</div\>\</nav\>JAVA SCRIPT
When you remove role="menuitem" from the dropdown items in the markup (to simplify ARIA usage), you will need to update the JavaScript selectors accordingly. The current JS uses selectors like [role="menuitem"] to find and manage keyboard focus on dropdown items. To maintain keyboard accessibility, replace these selectors with ones matching your updated markup, such as a class selector (e.g., .ds-menu-item) or another attribute.
Issue 3 of 4: Skipping Edit Menu
Describe the bug
Screen Reader VoiceOver (VO) skips the 3 dot edit menu entirely when reading through the page. It jumps focus from the H1 header to the window and then to the thumbnail. The edit menu is not accessible through the reader unless they manually key through the page.
Page
Item Page
WCAG Guideline
WCAG 1.3.1, 4.1.2, 2.1.1, 2.1.2
To Reproduce
Relevant code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c3947076920="" \_nghost-dspace-angular-c2948902503=""\>\<div \_ngcontent-dspace-angular-c2948902503="" role="menubar" class="dso-edit-menu d-flex"\>\<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted"\>\<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" ngbdropdown="" container="body" placement="bottom-right" class="dso-button-menu mb-1 ng-star-inserted dropdown"\>\<div \_ngcontent-dspace-angular-c2003421933="" container="body" class="d-flex flex-row flex-nowrap"\>\<button \_ngcontent-dspace-angular-c2003421933="" ngbdropdowntoggle="" role="menuitem" tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i \_ngcontent-dspace-angular-c2003421933="" class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<!----\>\<ul \_ngcontent-dspace-angular-c2003421933="" ngbdropdownmenu="" role="menu" class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-fw fa-pencil-alt fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-link-menu-item \_nghost-dspace-angular-c721316482="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c721316482="" role="menuitem" href="/entities/publication/08806560-a17a-4774-b063-d901b1335d70/edit/metadata" tabindex="0" class="ds-menu-item" data-test="link-menu-item.publication.page.edit"\>Edit this item\</a\>\</ds-link-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-eye-slash fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Request a withdrawal for this item" data-test="item.page.withdrawn"\>Request a withdrawal for this item\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-code-branch fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Create new version" data-test="item.page.version.create"\>Create new version\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<!----\>\</ul\>\</div\>\<!----\>\</ds-dso-edit-menu-expandable-section\>\<!----\>\</div\>\<!----\>\</div\>\</ds-dso-edit-menu\>Expected behavior
This is likely because of poor ARIA usage which makes VO interpret role=menubar as an instruction to jump back to the window menu. When the user does key to the edit menu, they are able to open it, but they can't key into the menu itself and go through the options. The VO commands do not work, and this is also because of the ARIA menu role, which makes screen readers behave differently. A contributing factor can also be that the menu items have role=presentation in the <li> attribute and then include an <a>, but the role=presentation is not necessary and conflicts with <a>.
Summary of Changes
REMOVE:
CHANGE:
Modal triggers ("Request a withdrawal" and "Create new version"):
From: <a href="javascript:void(0);">
To: <button type="button" aria-haspopup="dialog">
KEEP
Suggested fix / example code
\<ds-dso-edit-menu\>\<div class="dso-edit-menu d-flex"\>\<div class="ms-1"\>\<ds-dso-edit-menu-expandable-section\>\<div ngbdropdown container="body" placement="bottom-right" class="dso-button-menu mb-1 dropdown"\>\<div container="body" class="d-flex flex-row flex-nowrap"\>\<button ngbdropdowntoggle tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<ul ngbdropdownmenu class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-fw fa-pencil-alt fas"\>\</i\>\</div\>\<ds-link-menu-item\>\<a href="/entities/publication/08806560.../edit/metadata" tabindex="0" class="ds-menu-item"\>Edit this item\</a\>\</ds-link-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-eye-slash fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Request a withdrawal for this item"\>Request a withdrawal for this item\</button\>\</ds-onclick-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-code-branch fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Create new version"\>Create new version\</button\>\</ds-onclick-menu-item\>\</li\>\</ul\>\</div\>\</ds-dso-edit-menu-expandable-section\>\</div\>\</div\>\</ds-dso-edit-menu\>Issue 4 of 4: Broken Edit Menu Navigation
Describe the bug
When keying, the 3 dot edit menu options do not respond to the VoiceOver key command (VO+space), but it will respond to "space" alone. This is also a keyboard violation as screen reader users are unable to use the standard keying that should automatically work.
Page
Item Page
WCAG Guideline
WCAG 1.3.1, 4.1.2, 2.1.1, 2.1.2
To Reproduce
Relevant code
\<ds-dso-edit-menu \_ngcontent-dspace-angular-c3947076920="" \_nghost-dspace-angular-c2948902503=""\>\<div \_ngcontent-dspace-angular-c2948902503="" role="menubar" class="dso-edit-menu d-flex"\>\<div \_ngcontent-dspace-angular-c2948902503="" class="ms-1 ng-star-inserted"\>\<ds-dso-edit-menu-expandable-section \_nghost-dspace-angular-c2003421933="" class="ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" ngbdropdown="" container="body" placement="bottom-right" class="dso-button-menu mb-1 ng-star-inserted dropdown"\>\<div \_ngcontent-dspace-angular-c2003421933="" container="body" class="d-flex flex-row flex-nowrap"\>\<button \_ngcontent-dspace-angular-c2003421933="" ngbdropdowntoggle="" role="menuitem" tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i \_ngcontent-dspace-angular-c2003421933="" class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<!----\>\<ul \_ngcontent-dspace-angular-c2003421933="" ngbdropdownmenu="" role="menu" class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-fw fa-pencil-alt fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-link-menu-item \_nghost-dspace-angular-c721316482="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c721316482="" role="menuitem" href="/entities/publication/08806560-a17a-4774-b063-d901b1335d70/edit/metadata" tabindex="0" class="ds-menu-item" data-test="link-menu-item.publication.page.edit"\>Edit this item\</a\>\</ds-link-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-eye-slash fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Request a withdrawal for this item" data-test="item.page.withdrawn"\>Request a withdrawal for this item\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<li \_ngcontent-dspace-angular-c2003421933="" role="presentation" class="nav-item nav-link d-flex flex-row p-2 ng-star-inserted"\>\<div \_ngcontent-dspace-angular-c2003421933="" class="me-2 ng-star-inserted"\>\<i \_ngcontent-dspace-angular-c2003421933="" aria-hidden="true" class="fa-code-branch fa-fw fas ng-star-inserted"\>\</i\>\<!----\>\<!----\>\</div\>\<!----\>\<ds-onclick-menu-item \_nghost-dspace-angular-c580104809="" class="ng-star-inserted"\>\<a \_ngcontent-dspace-angular-c580104809="" role="menuitem" routerlinkactive="active" href="javascript:void(0);" class="ds-menu-item ng-star-inserted" title="Create new version" data-test="item.page.version.create"\>Create new version\</a\>\<!----\>\<!----\>\</ds-onclick-menu-item\>\<!----\>\</li\>\<!----\>\</ul\>\</div\>\<!----\>\</ds-dso-edit-menu-expandable-section\>\<!----\>\</div\>\<!----\>\</div\>\</ds-dso-edit-menu\>Expected behavior
This is likely because of poor ARIA usage which makes VO interpret role=menubar as an instruction to jump back to the window menu. When the user does key to the edit menu, they are able to open it, but they can't key into the menu itself and go through the options. The VO commands do not work, and this is also because of the ARIA menu role, which makes screen readers behave differently. A contributing factor can also be that the menu items have role=presentation in the <li> attribute and then include an <a>, but the role=presentation is not necessary and conflicts with <a>. Summary of Changes
REMOVE
CHANGE
Modal triggers ("Request a withdrawal" and "Create new version"):
From: <a href="javascript:void(0);">
To: <button type="button" aria-haspopup="dialog">
KEEP
Suggested fix / example code
\<ds-dso-edit-menu\>\<div class="dso-edit-menu d-flex"\>\<div class="ms-1"\>\<ds-dso-edit-menu-expandable-section\>\<div ngbdropdown container="body" placement="bottom-right" class="dso-button-menu mb-1 dropdown"\>\<div container="body" class="d-flex flex-row flex-nowrap"\>\<button ngbdropdowntoggle tabindex="0" class="dropdown-toggle btn btn-dark btn-sm" title="Options" aria-label="Options" aria-disabled="false" aria-expanded="false"\>\<i class="fa-ellipsis-vertical fa-fw fas"\>\</i\>\</button\>\</div\>\<ul ngbdropdownmenu class="dso-edit-menu-dropdown p-1 dropdown-menu" style="position: static;"\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-fw fa-pencil-alt fas"\>\</i\>\</div\>\<ds-link-menu-item\>\<a href="/entities/publication/08806560.../edit/metadata" tabindex="0" class="ds-menu-item"\>Edit this item\</a\>\</ds-link-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-eye-slash fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Request a withdrawal for this item"\>Request a withdrawal for this item\</button\>\</ds-onclick-menu-item\>\</li\>\<li class="nav-item nav-link d-flex flex-row p-2"\>\<div class="me-2"\>\<i aria-hidden="true" class="fa-code-branch fa-fw fas"\>\</i\>\</div\>\<ds-onclick-menu-item\>\<button type="button" aria-haspopup="dialog" class="ds-menu-item" title="Create new version"\>Create new version\</button\>\</ds-onclick-menu-item\>\</li\>\</ul\>\</div\>\</ds-dso-edit-menu-expandable-section\>\</div\>\</div\>\</ds-dso-edit-menu\>Related work
#5639