elementor icon indicating copy to clipboard operation
elementor copied to clipboard

♿ 🐞 Bug Report: Mega Menu Accessibility is not intuitive

Open Daveden2 opened this issue 9 months ago • 52 comments

Prerequisites

  • [X] I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
  • [X] The issue still exists against the latest stable version of Elementor.

Description

After seeking feedback from various accessibility groups, it has become evident that the current implementation of the mega menu utilising the role="menubar" attribute lacks intuitiveness and raises several accessibility concerns.

Issues

This bug report outlines three issues:

  1. Non-intuitive Keyboard Navigation: Keyboard users are not accustomed to navigating navigation menus solely using arrow keys. Furthermore, this behaviour is inconsistent as only top-level menu items utilise arrow keys, while links within the dropdowns use the tab key for navigation. This inconsistency can be confusing for users.
  2. Screen Reader Compatibility: Screen readers like NVDA encounter issues with the dropdown button since it is not recognized as part of the role="menubar" specification,
  3. Missing role="menuitem" for Dropdown Links: While the dropdown content has the appropriate role="menu" attribute, the links within the dropdown (added via nested containers) lack the necessary role="menuitem". This omission results in accessibility errors when tested with accessibility evaluation tools.

Proposed Solution

  1. Remove the role="menubar" attribute from the mega menu, and use the regular button to expand the dropdown content.
  2. Consistently use the tab key for navigation throughout the menu.
  3. Provide a control for each toplevel menu item to toggle between two menu structures for its dropdown content:
  • Simple Dropdown List Structure <ul><li><a>Dropdown Subitems</a></li></ul>, and
  • Nested Container Structure

Steps to reproduce

  1. Install the latest version of Elementor 3.16+
  2. Activate the menu feature under Elementor > Settings > Features and other necessary features
  3. Add a new menu widget to a new container
  4. Add some menu items and some dropdown content for each menu item
  5. Use the NVDA screen reader and a keyboard to navigate through the top level menu items, once it gets to a dropdown toggle, you'll no longer be able to move to the next menu item

Isolating the problem

  • [ ] This bug happens with only Elementor plugin active (and Elementor Pro).
  • [X] This bug happens with a Blank WordPress theme active (Hello theme).
  • [X] I can reproduce this bug consistently following the steps above.

System Info

Click to reveal

== Server Environment ==
	Operating System: Linux
	Software: LiteSpeed
	MySQL version: MariaDB Server v10.5.19
	PHP Version: 8.1.18
	PHP Memory Limit: 2048M
	PHP Max Input Vars: 5000
	PHP Max Post Size: 2048M
	GD Installed: Yes
	ZIP Installed: Yes
	Write Permissions: All right
	Elementor Library: Connected

== WordPress Environment ==
	Version: 6.3.1
	Site URL: https://ele-templates.daveden.co.uk
	Home URL: https://ele-templates.daveden.co.uk
	WP Multisite: No
	Max Upload Size: 2 GB
	Memory limit: 40M
	Max Memory limit: 2048M
	Permalink Structure: /%postname%/
	Language: en-US
	Timezone: 0
	Debug Mode: Inactive

== Theme ==
	Name: Hello Elementor Child
	Version: 2.0.0
	Author: Elementor Team
	Child Theme: Yes
	Parent Theme Name: Hello Elementor
	Parent Theme Version: 2.8.1
	Parent Theme Author: Elementor Team

== User ==
	Role: administrator
	WP Profile lang: en_US
	User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0

== Active Plugins ==
	Duplicator Pro
		Version: 4.5.12.1
		Author: Duplicator

	Elementor
		Version: 3.16.4
		Author: Elementor.com

	Elementor Pro
		Version: 3.16.2
		Author: Elementor.com

	HappyFiles Pro
		Version: 1.8.3
		Author: Codeer

	Hostinger
		Version: 1.7.0
		Author: Hostinger

	Hostinger AI Assistant
		Version: 1.4.1
		Author: Hostinger

	iThemes Security
		Version: 8.1.8
		Author: iThemes

	JetBlocks For Elementor
		Version: 1.3.8
		Author: Crocoblock

	JetEngine
		Version: 3.2.5
		Author: Crocoblock

	JetSearch
		Version: 3.1.2
		Author: Crocoblock

	JetSmartFilters
		Version: 3.2.1
		Author: Crocoblock

	LiteSpeed Cache
		Version: 5.6
		Author: LiteSpeed Technologies


== Elements Usage ==
	
	header : 1
		container : 1
		image : 1
		nav-menu : 1
	page : 1
		blockquote : 1
		container : 14
		heading : 2
		image : 3
		image-box : 9
		image-carousel : 1
		text-editor : 4
	popup : 1
		container : 1
		icon-list : 1
		image : 1
		social-icons : 1
	section : 1
		container : 10
		heading : 7
		icon-list : 1
		image : 6
		nav-menu : 1
		nested-accordion : 1
		social-icons : 1
		text-editor : 2
	wp-post : 0
		accordion : 1
		blockquote : 3
		button : 37
		call-to-action : 16
		code-highlight : 1
		container : 318
		divider : 4
		form : 1
		gallery : 1
		heading : 71
		html : 11
		icon : 2
		icon-box : 2
		icon-list : 29
		image : 54
		image-box : 60
		image-carousel : 3
		image-gallery : 1
		jet-ajax-search : 1
		jet-hamburger-panel : 1
		jet-listing-grid : 1
		loop-grid : 10
		mega-menu : 5
		nested-accordion : 2
		nested-carousel : 3
		nested-tabs : 3
		price-table : 3
		search-form : 2
		share-buttons : 1
		shortcode : 2
		social-icons : 3
		text-editor : 22
	wp-page : 2
		container : 11
		mega-menu : 1
		nested-accordion : 1
		nested-tabs : 1
	loop-item : 17
		container : 13
		heading : 13
		image : 2
		jet-listing-dynamic-image : 1
		post-info : 4
		theme-post-excerpt : 4
		theme-post-featured-image : 2
		theme-post-title : 4


== Settings ==
	
	cpt_support: post, page, lab-pages, demo, tut-demo
	disable_color_schemes: yes
	disable_typography_schemes: yes
	allow_tracking: yes
	unfiltered_files_upload: 1
	font_display: swap


== Features ==
	Custom Fonts: 7
	Custom Icons: 0

== Integrations ==
	


== Elementor Experiments ==
	Optimized DOM Output: Active by default
	Improved Asset Loading: Active by default
	Improved CSS Loading: Inactive
	Inline Font Icons: Active
	Additional Custom Breakpoints: Active by default
	admin_menu_rearrangement: Inactive by default
	Flexbox Container: Active
	Upgrade Swiper Library: Active by default
	Grid Container: Active
	Default to New Theme Builder: Active by default
	Hello Theme Header &amp; Footer: Active by default
	Editor Top Bar: Active
	Landing Pages: Inactive
	Nested Elements: Active
	Lazy Load Background Images: Inactive by default
	Pages Panel: Inactive by default
	Global Style Guide: Active by default
	Page Transitions: Active by default
	Notes: Active by default
	Form Submissions: Active by default
	Scroll Snap: Active by default
	Menu: Active
	Taxonomy Filter: Active


== Log ==
	
Log: showing 20 of 232023-09-14 15:21:33 [info] Elementor data updater process has been queued. [array (
  'plugin' => 'Elementor',
  'from' => '3.16.2',
  'to' => '3.16.3',
)]
2023-09-14 15:21:33 [info] Elementor/Upgrades - _on_each_version Finished 
2023-09-14 15:21:33 [info] Elementor/Upgrades - _v_3_17_0_site_settings_updates Start  
2023-09-14 15:21:33 [info] Elementor/Upgrades - _v_3_17_0_site_settings_updates Finished 
2023-09-14 15:21:33 [info] Elementor data updater process has been completed. [array (
  'plugin' => 'Elementor',
  'from' => '3.16.2',
  'to' => '3.16.3',
)]
2023-09-14 15:30:43 [info] elementor-pro::elementor_pro_updater Started 
2023-09-14 15:30:43 [info] Elementor Pro/Upgrades - _on_each_version Start  
2023-09-14 15:30:43 [info] Elementor Pro/Upgrades - _on_each_version Finished 
2023-09-14 15:30:43 [info] Elementor data updater process has been completed. [array (
  'plugin' => 'Elementor Pro',
  'from' => '3.16.0',
  'to' => '3.16.1',
)]
2023-09-20 20:46:57 [info] Elementor data updater process has been queued. [array (
  'plugin' => 'Elementor',
  'from' => '3.16.3',
  'to' => '3.16.4',
)]
2023-09-20 20:46:58 [info] Elementor data updater process has been queued. [array (
  'plugin' => 'Elementor Pro',
  'from' => '3.16.1',
  'to' => '3.16.2',
)]
2023-09-20 20:47:00 [info] elementor-pro::elementor_pro_updater Started 
2023-09-20 20:47:00 [info] Elementor Pro/Upgrades - _on_each_version Start  
2023-09-20 20:47:00 [info] Elementor Pro/Upgrades - _on_each_version Finished 
2023-09-20 20:47:00 [info] elementor::elementor_updater Started 
2023-09-20 20:47:00 [info] Elementor/Upgrades - _on_each_version Start  
2023-09-20 20:47:03 [info] Elementor/Upgrades - _on_each_version Finished 
2023-09-20 20:47:03 [info] Elementor/Upgrades - _v_3_17_0_site_settings_updates Start  
2023-09-20 20:47:03 [info] Elementor/Upgrades - _v_3_17_0_site_settings_updates Finished 
2023-09-20 20:47:03 [info] Elementor data updater process has been completed. [array (
  'plugin' => 'Elementor',
  'from' => '3.16.3',
  'to' => '3.16.4',
)]

JS: showing 8 of 8JS: 2023-09-13 14:43:21 [error X 4][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/4fdaa70e951ad90db2f2.bundle.min.js:2:7765] t.target.closest(...) is null 
JS: 2023-09-13 14:45:52 [error X 10][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/editor.min.js?ver=3.16.2:3:803916] this.store.find(...) is undefined 
JS: 2023-09-15 06:48:00 [error X 2][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/frontend.min.js?ver=3.16.3:2:30893] elementor.settings.page is undefined 
JS: 2023-09-16 07:15:25 [error X 2][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/4fdaa70e951ad90db2f2.bundle.min.js:2:7786] Cannot read properties of null (reading &#039;dataset&#039;) 
JS: 2023-09-16 19:00:13 [error X 1][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/editor.min.js?ver=3.16.3:3:1108873] V is null 
JS: 2023-09-16 19:26:26 [error X 1][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/editor.min.js?ver=3.16.3:3:803742] T.originalEvent.key is undefined 
JS: 2023-09-17 14:03:08 [error X 6][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/editor.min.js?ver=3.16.3:3:1108875] Cannot read properties of null (reading &#039;getBoundingClientRect&#039;) 
JS: 2023-09-17 15:27:14 [error X 1][https://ele-templates.daveden.co.uk/wp-content/plugins/elementor/assets/js/editor.min.js?ver=3.16.3:3:601264] Cannot read properties of null (reading &#039;id&#039;) 

PHP: showing 11 of 11PHP: 2023-09-14 18:38:16 [warning X 5][../wp-content/plugins/elementor/app/modules/import-export/module.php::753] Attempt to read property &quot;label&quot; on null [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-14 18:38:19 [warning X 4][../wp-content/plugins/elementor/core/common/modules/ajax/module.php::175] Undefined array key &quot;data&quot; [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-14 18:38:20 [warning X 30][../wp-content/plugins/elementor-pro/core/app/modules/site-editor/data/endpoints/templates.php::150] Undefined array key &quot;condition_type&quot; [array (
  'trace' => '
#0: ../wp-content/plugins/elementor-pro/core/app/modules/site-editor/data/endpoints/templates.php(150): Elementor\Core\Logger\Manager -> rest_error_handler()
#1: ElementorPro\Core\App\Modules\SiteEditor\Data\Endpoints\Templates -> normalize_template_json_item()
#2: ../wp-content/plugins/elementor-pro/core/app/modules/site-editor/data/endpoints/templates.php(120): class type array_map()
#3: ../wp-content/plugins/elementor-pro/core/app/modules/site-editor/data/endpoints/templates.php(59): ElementorPro\Core\App\Modules\SiteEditor\Data\Endpoints\Templates -> normalize_templates_json()
#4: ../wp-content/plugins/elementor/data/base/endpoint.php(158): ElementorPro\Core\App\Modules\SiteEditor\Data\Endpoints\Templates -> get_items()
',
)]
PHP: 2023-09-15 10:25:27 [warning X 1][../wp-content/plugins/elementor/core/files/file-types/svg.php::234] simplexml_load_file(https://ele-templates.daveden.co.uk/wp-content/uploads/2023/09/headphone-light.svg): Failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
 [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-15 22:37:39 [error X 1][../wp-content/plugins/elementor/core/wp-api.php::26] Uncaught Error: Call to undefined function Elementor\Core\get_plugins() in ../wp-content/plugins/elementor/core/wp-api.php:26
Stack trace:
#0 ../wp-content/plugins/elementor/modules/compatibility-tag/base-module.php(96): Elementor\Core\Wp_Api-&gt;get_plugins()
#1 ../wp-content/plugins/elementor/modules/compatibility-tag/base-module.php(58): Elementor\Modules\CompatibilityTag\Base_Module-&gt;get_plugins_with_header()
#2 ../wp-content/plugins/elementor/modules/compatibility-tag/module.php(57): Elementor\Modules\CompatibilityTag\Base_Module-&gt;get_plugins_to_check()
#3 ../wp-content/plugins/elementor/modules/compatibility-tag/base-module.php(148): Elementor\Modules\CompatibilityTag\Module-&gt;get_plugins_to_check()
#4 ../wp-includes/class-wp-hook.php(310): Elementor\Modules\CompatibilityTag\Base_Module-&gt;Elementor\Modules\CompatibilityTag\{closure}()
#5 ../wp-includes/class-wp-hook.php(334): WP_Hook-&gt;apply_filters()
#6 ../wp-includes/plugin.php(517): WP_Hook-&gt;do_action()
#7 ../wp-content/plugins/elementor/modules/system-info/module.php(340): do_action()
#8 ../wp-content/plugins/elementor/includes/tracker.php(241): Elementor\Modules\System_Info\Module::get_allowed_reports()
#9 ../wp-content/plugins/elementor/includes/tracker.php(530): Elementor\Tracker::get_system_reports_data()
#10 ../wp-content/plugins/elementor/includes/tracker.php(141): Elementor\Tracker::get_tracking_data()
#11 ../wp-includes/class-wp-hook.php(310): Elementor\Tracker::send_tracking_data()
#12 ../wp-includes/class-wp-hook.php(334): WP_Hook-&gt;apply_filters()
#13 ../wp-includes/plugin.php(565): WP_Hook-&gt;do_action()
#14 ../wp-cron.php(191): do_action_ref_array()
#15 {main}
  thrown [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-16 18:57:44 [warning X 10][../wp-content/plugins/elementor/modules/history/revisions-manager.php::363] Trying to access array offset on value of type null [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-16 19:01:57 [warning X 20][../wp-content/plugins/elementor-pro/modules/assets-manager/asset-types/fonts-manager.php::252] Undefined array key &quot;editor_post_id&quot; [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-17 14:11:02 [notice X 31][../wp-content/plugins/elementor/includes/base/controls-stack.php::228] hexdec(): Passing null to parameter #1 ($hex_string) of type string is deprecated [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-17 18:39:50 [notice X 9][../wp-content/plugins/elementor/includes/utils.php::727] strtolower(): Passing null to parameter #1 ($string) of type string is deprecated [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-17 22:43:55 [warning X 8][../wp-content/plugins/elementor/includes/base/controls-stack.php::1427] Undefined array key &quot;_element_vertical_align_tablet&quot; [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]
PHP: 2023-09-18 03:39:24 [error X 1][../wp-content/plugins/elementor-pro/modules/loop-builder/skins/skin-loop-base.php::144] Uncaught Error: Call to undefined method Elementor\Core\DocumentTypes\Post::print_content() in ../wp-content/plugins/elementor-pro/modules/loop-builder/skins/skin-loop-base.php:144
Stack trace:
#0 ../wp-content/plugins/elementor-pro/modules/loop-builder/skins/skin-loop-base.php(129): ElementorPro\Modules\LoopBuilder\Skins\Skin_Loop_Base-&gt;render_post_content()
#1 ../wp-content/plugins/elementor-pro/modules/posts/skins/skin-base.php(876): ElementorPro\Modules\LoopBuilder\Skins\Skin_Loop_Base-&gt;render_post()
#2 ../wp-content/plugins/elementor-pro/modules/loop-builder/skins/skin-loop-base.php(89): ElementorPro\Modules\Posts\Skins\Skin_Base-&gt;render()
#3 ../wp-content/plugins/elementor/includes/base/skin-base.php(79): ElementorPro\Modules\LoopBuilder\Skins\Skin_Loop_Base-&gt;render()
#4 ../wp-content/plugins/elementor/includes/base/widget-base.php(607): Elementor\Skin_Base-&gt;render_by_mode()
#5 ../wp-content/plugins/elementor/includes/base/widget-base.php(750): Elementor\Widget_Base-&gt;render_content()
#6 ../wp-content/plugins/elementor/includes/base/element-base.php(464): Elementor\Widget_Base-&gt;print_content()
#7 ../wp-content/plugins/elementor/includes/base/element-base.php(1375): Elementor\Element_Base-&gt;print_element()
#8 ../wp-content/plugins/elementor/includes/base/element-base.php(464): Elementor\Element_Base-&gt;print_content()
#9 ../wp-content/plugins/elementor/core/base/document.php(1739): Elementor\Element_Base-&gt;print_element()
#10 ../wp-content/plugins/elementor/core/base/document.php(1134): Elementor\Core\Base\Document-&gt;print_elements()
#11 ../wp-content/plugins/elementor/includes/frontend.php(1179): Elementor\Core\Base\Document-&gt;print_elements_with_wrapper()
#12 ../wp-content/plugins/elementor/includes/frontend.php(1074): Elementor\Frontend-&gt;get_builder_content()
#13 ../wp-includes/class-wp-hook.php(310): Elementor\Frontend-&gt;apply_builder_in_content()
#14 ../wp-includes/plugin.php(205): WP_Hook-&gt;apply_filters()
#15 ../wp-includes/post-template.php(256): apply_filters()
#16 ../wp-content/themes/hello-elementor/template-parts/single.php(25): the_content()
#17 ../wp-includes/template.php(787): require(&#039;/home/u49697372...&#039;)
#18 ../wp-includes/template.php(720): load_template()
#19 ../wp-includes/general-template.php(206): locate_template()
#20 ../wp-content/themes/hello-elementor/index.php(21): get_template_part()
#21 ../wp-includes/template-loader.php(106): include(&#039;/home/u49697372...&#039;)
#22 ../wp-blog-header.php(19): require_once(&#039;/home/u49697372...&#039;)
#23 ../index.php(17): require(&#039;/home/u49697372...&#039;)
#24 {main}
  thrown [array (
  'trace' => '
#0: Elementor\Core\Logger\Manager -> shutdown()
',
)]



== Elementor - Compatibility Tag ==
	
	Elementor Pro: Compatible
	JetBlocks For Elementor: Incompatible

== Elementor Pro - Compatibility Tag ==
	
	JetBlocks For Elementor: Incompatible

Daveden2 avatar Sep 21 '23 11:09 Daveden2

I'll second this. It's not expected that a navigation menu on a website will use menubar. The Menubar role is intended for desktop applications, not websites.

It's good to have arrow key support in the navigation, but it should also work with tabs too. Keyboard only users (who are not using screen readers and will not get notified that this navigation uses the menubar role) will not know how to interact with this nav.

Here's an example of a good nav menu on the WordPress Accessibility Day website. You can also watch this recording of a meetup on accessible navigation.

amberhinds avatar Sep 21 '23 14:09 amberhinds

Also, the aria-label on the nav itself is junky. It needs to label the menu to distinguish it from other nav elements on the page. Currently, the nav looks like this: <nav class="e-n-menu" data-widget-number="241" aria-label="Menu | Open (Enter or Space) | Return (Escape) | Other Menu Items (Arrow, Home &amp; End Keys)" data-touch-mode="false" data-layout="horizontal">

The aria-label needs to name the nav link this: <nav aria-label="Primary"> or <nav aria-label="Sidebar">

amberhinds avatar Sep 21 '23 15:09 amberhinds

@nicholaszein This is my feedback:

@Daveden2 We will discuss this internally. Thank you so much for your thorough analysis.

@amberhinds I am not really with your analysis. I can't find evidence that the 'menubar role is intended for desktop applications'. W3.org suggests using 'menubar' in various places, such as https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/.

Also, I am not sure where the 'aria-label' content has been prescribed to be like that.

hein-obox avatar Sep 25 '23 18:09 hein-obox

@hein-obox, thank you for your response. I'm pleased to know that the team will be looking into it further.

In response to your enquiries:

  • The purpose of an "aria-label," as the name suggests, is to provide a recognisable name or label for an element, specifically in this context, for the "nav" element. You can find more details in the W3C ARIA documentation.
  • In the context of navigation menus, the "aria-label" attribute becomes particularly useful when there are multiple "nav" elements on a page, such as the primary navigation menu, breadcrumbs, table of contents, etc. You can refer to this article on aditus.io for further insights. That's why I asked during the beta testing if it was possible to allow users to add their own aria-label (similar to what the other page builder does).
  • Regarding the use of role="menubar", you can refer to the MDN documentation linked by @amberhinds. It emphasises that the role="menubar" is quite complex and generally unnecessary for typical site navigation, as also highlighted by the W3C ARIA Authoring Practices Guide.

For more information, you may want to explore this PDF slide that I found from Deque: Deque Accessible Mega Menus.

Additionally, based on the examples I've come across, a navigation menu using role="menubar" often functions as a contextual menu, similar to desktop applications. Typically, the top-level item doesn't contain a separate link but rather serves to describe and toggle a dropdown menu. For a practical illustration, you can visit this example from Deque University. Although it's possible to add a link to the top-level menu, doing so would most likely yield unexpected results.

In conclusion, I believe that the preferred approach should be the use of the disclosure (flyout) pattern for navigation menus, which is relatively straightforward to implement and doesn't require an extensive amount of ARIA information.

Daveden2 avatar Sep 25 '23 20:09 Daveden2

Hi @Daveden2,

Thank you for your feedback, I agree with most of your points.

My main concern was with @amberhinds emphasis on what we 'have to do', while I believe there is the freedom to make our own choices and still stick to the W3C Aria guidelines.

hein-obox avatar Sep 26 '23 07:09 hein-obox

Hi Elementor folks,

I second the issues and proposed fixes in @Daveden2’s post, and would like to add another, regarding the current implementation of aria-label on nav elements:

Currently, “Menu” and”Wordpress Menu” Elementor widgets use a <nav> HTML element (without option for user to change the HTML element), which (in the case of the newer “Menu” widget) includes an arial-label of “Menu | Open (Enter or Space) | Return (Escape) | Other Menu Items (Arrow, Home & End Keys)”.

If multiple Menu widgets appear on the same page (for instance a primary menu in the site header, with a set of secondary links in the site footer), a user navigating the web page via screen reader will thus be presented with multiple navigation landmarks with no accessible way to differentiate them.

(This cannot currently be fixed via the Attributes feature, as adding an aria-label here passes it to the menu widget’s parent div element, and not to the nav element itself — the actual nav element still keeps the "hard-coded" aria-label with the keyboard instructions.)

I would propose that a control be exposed in the UI, as soon as possible, allowing the user to override the aria-label on the nav element itself.

wes-davis avatar Oct 25 '23 19:10 wes-davis

Sorry for the delayed response. @hein-obox, something to keep in mind is that accessibility is not just for people who are using screen readers. A lot of people are sighted and have no need for a screen reader, but cannot use a mouse and are keyboard only users.

While your nav menu might provide some auditory explanation for screen reader users about how to interact with it, a sighted user will not have that information.

The vast majority of websites allow users to tab through menu items and this is the expected behavior. Can you choose not to support the Tab key and require arrow navigation? Yes. But when that is not the expected way to navigate a website, many users will get stuck. In fact, I was hung up on it the first time I encountered it and thought that it was completely broken. I spent ~10 minutes inspecting the code trying to figure out why the tab key didn't work. A typical user, with no dev skills would probably just abandon a site.

amberhinds avatar Oct 25 '23 21:10 amberhinds

Great to see this reported. Here is the reported issue from axe DevTools Pro:

image

bobbyomari avatar Oct 26 '23 19:10 bobbyomari

I hope Elementor team will the accessibility issue a priority. Users should be able to navigate the mega menu using just the keyboard. Thanks in advance!

websubst avatar Oct 30 '23 18:10 websubst

@Daveden2 @doronwolf @amberhinds

We are working on an update of the Mega Menu Accessibility.

I have tried to follow your suggestions:

  1. Role= 'Menubar' removed.
  2. Implemented the tab key for navigation.
  3. You can toggle between top and dropdown levels using the tab and shifttab keys as well.

I have followed the markup of the fly-out menus, and used the following websites as a reference: https://www.w3.org/WAI/tutorials/menus/flyout/#flyoutnavkbbtn https://www.ebay.com/

Could please review our work using this demo URL: https://deliverycompany-clone.elementor.cloud/.

We haven't added a control to edit the Menu and Menu Toggle aria label yet, but we have an additional task to implement that. See a screenshot for reference: Screenshot 2024-02-02 at 22 03 51

hein-obox avatar Feb 02 '24 20:02 hein-obox

Hi @hein-obox

I conducted a quick test of the Elementor test site plus the eBay menu and the W3C menu. Here are my observations:

The Positives

  1. I successfully navigated through the top-level menu items using the tab key.
  2. The Elementor menu no longer includes the lengthy announcement for the nav's aria label.
  3. Submenu items open on hover

Issues Noticed

  1. While using NVDA / Narrator, I encountered an issue with the toggle button for Elementor; it was unresponsive without disabling browse mode. However, it worked as expected for both the eBay and W3C menus.
  2. While testing with mobile voiceover and talkback, the dropdown for the Elementor test site opened on tap. Unfortunately, I couldn't access the dropdown content.
  3. In the case of the W3C menu, when I hover over the top menu (toggle), it opens the menu on hover. Then, clicking on the icon closes the submenu. Whereas, the Elementor test site's menu does not respond in this way. That might be what is causing the dropdown not to work when NVDA or Narrator is active

Daveden2 avatar Feb 02 '24 23:02 Daveden2

Thank you so much for your feedback @Daveden2

This reminds me to test with the NVDA tool. I will get a Windows laptop to do so.

Are you happy with the (absence of) aria-labels and with the overall HTML structure of the menu? I have tried to stick to the given examples as much as possible.

The menu has an option for the submenus to be opened on 'hover' or on 'click'. I have changed the settings to 'click'. Does that change the screenreader behavior?

hein-obox avatar Feb 03 '24 06:02 hein-obox

@hein-obox, it seems to be doing the job well on my desktop computer.

Mobile Screen Reader Test

I noticed that using VoiceOver or TalkBack on mobile, the dropdown content is sort of disconnected from the menu items.

When I trigger the hamburger menu, I have to swipe to the end of the list of top-level links before I can access the dropdown content.

HTML Content Placement

On a side note, like Maxime mentioned a few times, in the html the dropdown content should ideally directly follow the trigger button within the same <li>

So, something link

<nav>
   <ul>
      <li class="menu-item>
         <a class=menu-item__link></a>
         <button class="submenu-trigger"></button>
         <ul class="submenu"><li class="submenu-item"><a></li></ul>
      </li>
   </ul>
</nav>

Aria Labels

I feel that the aria-label on the buttons should be changed to something like "item_name submenu". The reason is that right now, whether the menu item is opened or closed, it'll still first read "Expand: item_name"

If possible, we could switch to using a visually hidden text rather than aria-labels. Maybe @amberhinds could help me out on this one.

Conclusion

These are just my opinions and observations. I wish a native screen reader user or certified accessibility auditor would chime in.

Daveden2 avatar Feb 03 '24 20:02 Daveden2

@rami-elementor For your reference.

hein-obox avatar Feb 04 '24 08:02 hein-obox

@Daveden2 - How were you able to tab navigate the Mega Menu? I set up just a very simple one with no drop downs or sub items, and it will not tab navigate. I do not see Accessibility Settings in the latest version of Elementor 3.19.x. The menu on this page is not really tab navigable https://deliverycompany-clone.elementor.cloud/. And you can't keyboard navigate the drop downs either. The focus does not go to the drop down and instead to the page, so if you use the keyboard, you end up keyboard navigating the page which is now hidden behind the drop down.

The Mega Menu is still far from accessible. How many more months or years is the plan for this to be accessible?

askwpgirl avatar Feb 06 '24 01:02 askwpgirl

@askwpgirl, the current plugin version of the mega menu is still not tab navigable. My recent comments were in response to testing the links provided by @hein-obox

This is weird. When I test the page on my Windows PC using Chrome, I can navigate to the links using the tab key just fine. image

Upon retesting, I've identified another bug: while the links are visible within the top menu items, they can't be activated. When clicking the "Kids" menu item, the dropdown menu activates instead of directing me to the associated link. Interestingly, the https://elementor.com link appears on hover, suggesting the link itself is present but is being blocked.

Daveden2 avatar Feb 06 '24 04:02 Daveden2

Yes, I see why I was confused. The top level items except the two Kids items do not have <a> tag, so they are not links, hence why they can't be activated. And if they are not links, they should not have focus -- only the icon would have focus as a "button".

Can you add links to those items?

Ideally, how normally accessible menus work is as follows:

  • Ability to tab navigate to all items in the top level.
  • Activation of drop down menu via the icon using the return key. This basically functions like a button and is correct. This is something Elementor did improve by having the icon separate from the menu item. Amber Hinds and I went over this a few months ago, and she agreed this part was more accessible than the old Elementor menu.
  • Arrow key navigation to items in the drop down.

What Elementor developers got mixed up was that they used arrow navigation for main level and tab navigation for drop down items when it should be the opposite.

What they got right was the drop down icon being a separate element that is activated on return key and functions like a button.

You are getting very close in your mockup! Amber would be great to consult with on any other tweaks that needs.

askwpgirl avatar Feb 06 '24 05:02 askwpgirl

@askwpgirl and @Daveden2 Thank you so much for your feedback. I found a bug in our code yesterday relating to the NVDA screen reader. I have implemented a fix, and I am still testing. I will update you once I having finished testing.

hein-obox avatar Feb 06 '24 07:02 hein-obox

@Daveden2 About the menu links: in which browser did you have that issue? And was it with the mouse click or with the Enter key?

I have tested it with Chrome (Mac), Edge (Windows), Edge + NVDA (Windows)

I have done some updates around this yesterday, and I will check again today.

Please a hard refresh before testing, because I have update the plugin yesterday.

hein-obox avatar Feb 06 '24 07:02 hein-obox

@Daveden2 We were able to reproduce the bug indicated. I will update the code later today.

hein-obox avatar Feb 06 '24 08:02 hein-obox

@Daveden2 Could you please test it one more time? https://deliverycompany-clone.elementor.cloud/

We made one tweak to the logic. After clicking through all items in a dropdown, it will take you back to the dropdown button. This for internal consistency with our other Accessibility functionalities inside Elementor.

hein-obox avatar Feb 06 '24 12:02 hein-obox

@askwpgirl

Can you add links to those items?

It is possible to add links to the items, but that is up to user to decide. Menu items without links won't receive the focus.

Ability to tab navigate to all items in the top level. That is how it works.

Activation of drop down menu via the icon using the return key. Implemented.

Arrow key navigation to items in the drop down. We have decided not to implement that. The user can use the 'Tab' key to go into the dropdown. We have followed the examples of the fly out menu on the following websites: https://www.w3.org/WAI/tutorials/menus/flyout/#flyoutnavkbbtn https://www.ebay.com/

None of them are using arrow keys. I have completely removed the arrow key functionality.

hein-obox avatar Feb 06 '24 12:02 hein-obox

@amberhinds @wes-davis I have still fighting to get an approval to make the Aria Labels editable, but I haven't received approval for that yet from the product team.

hein-obox avatar Feb 06 '24 12:02 hein-obox

@askwpgirl yeah arrow key navigation is an optional feature. It might be nice to be able to both use the tab key and the arrow key.

@hein-obox cool! I'll test it out again later this evening, when I get the chance.

I did notice while testing earlier this morning that the dropdown button included a "close:" text.

I feel that isn't necessary. Just the menu item name with a suffix of submenu might be sufficient. The aria-expanded should already tell the user if it is open or close.

The same way you don't write for the top level links, go to home page, go to about us page, go to contact us page, etc. You simply write home, about us, contact us, etc. The user can understand that it is a link which opens that page.

Same situation for a hamburger menu. You don't need to write "expand mobile menu". You simply write "mobile menu"

Daveden2 avatar Feb 06 '24 13:02 Daveden2

@Daveden2

About the 'close: ' text, we have some internal debate about that. I am not sure if I can change that :).

Btw, you are a star. Thank you so much for your support.

hein-obox avatar Feb 06 '24 14:02 hein-obox

@rami-elementor For your information. @Daveden2 isn't a fan of the addition of the 'close :' text.

hein-obox avatar Feb 06 '24 14:02 hein-obox

Hi! Sorry, I'm late to the party. Busy weekend with kids. I can test that demo later tonight and post some feedback.

amberhinds avatar Feb 06 '24 14:02 amberhinds

@rami-elementor For your information. @Daveden2 isn't a fan of the addition of the 'close :' text.

I understand, but we have to create a consistent experience across all Elementor widgets. If we choose to change this, we will have to change the texts in other widgets too. Therefor, for this task, I prefer to keep the open/close labels.

We can review this topic again, as a separate task. For that we will have to map all the places where we have expand/collapse capabilities and update them all. Again, for consistency...

rami-elementor avatar Feb 06 '24 15:02 rami-elementor

@hein-obox and @rami-elementor, after finally testing the demo out again on my PC, I can now say that I don't have complaints about how it was announced (personal opinion). The menu also worked well on mouse hover and keyboard interaction with NVDA active. Thank you all for everything you do!

I'll leave @amberhinds and @askwpgirl to run their tests and provide feedback, including comments about the structure of the HTML elements.

Daveden2 avatar Feb 06 '24 19:02 Daveden2

@Daveden2 Amazing! Thanks a million.

hein-obox avatar Feb 06 '24 19:02 hein-obox

This is a huge improvement! Thanks so much for your work on it @hein-obox! 🙌

Here are my recommendations after testing:

  1. It's actually a dark pattern to change the labels of buttons and can be problematic for screen reader users, so I would remove the open/close that you have here:
<button id="e-n-menu-dropdown-icon-2225" class="e-n-menu-dropdown-icon e-focus" data-tab-index="5" aria-haspopup="true" aria-expanded="false" aria-controls="e-n-menu-content-2225" data-focus-index="6">
						<span class="e-n-menu-dropdown-icon-opened">
							<svg aria-hidden="true" class="e-font-icon-svg e-fas-angle-up" viewBox="0 0 320 512" xmlns="http://www.w3.org/2000/svg"><path d="M177 159.7l136 136c9.4 9.4 9.4 24.6 0 33.9l-22.6 22.6c-9.4 9.4-24.6 9.4-33.9 0L160 255.9l-96.4 96.4c-9.4 9.4-24.6 9.4-33.9 0L7 329.7c-9.4-9.4-9.4-24.6 0-33.9l136-136c9.4-9.5 24.6-9.5 34-.1z"></path></svg>							<span class="elementor-screen-only">Close KIDS</span>
						</span>
						<span class="e-n-menu-dropdown-icon-closed">
							<svg aria-hidden="true" class="e-font-icon-svg e-fas-angle-down" viewBox="0 0 320 512" xmlns="http://www.w3.org/2000/svg"><path d="M143 352.3L7 216.3c-9.4-9.4-9.4-24.6 0-33.9l22.6-22.6c9.4-9.4 24.6-9.4 33.9 0l96.4 96.4 96.4-96.4c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9l-136 136c-9.2 9.4-24.4 9.4-33.8 0z"></path></svg>							<span class="elementor-screen-only">Open KIDS</span>
						</span>
					</button>

You don't need to say open or close because the aria-expanded attribute is what communicates if it's currently open or closed and what the button will do. I would remove the text from these span tags and just add an aria-label on the button. The aria-label should make it more clear that it's a submenu (I.e. "Kids submenu", "men submenu" etc.).

  1. The submenu buttons should work on click too. Currently, the submenus open on hover or keyboard interaction with the button. I'd ensure that they can be opened and closed by click on the button with a mouse as well. This is helpful for users who are mouse users but may have more jittery movements or accidentally leave the subnav.

  2. The aria-label for the nav tag (from your screenshot above) is definitely needed. If you're putting default text in there it shouldn't be "Menu" though. The aria-label on the nav tag should describe the kind of navigation it is - so for example this would say "primary".

Do you have the ability to edit or add helper text? If not, I would change the label so people know what to put there: "Describe menu location or contents for screen reader users."

  1. I would not allow users to be able to define the aria-label for the mobile toggle. They're probably just going to put incorrect things there, so I would not include this field. Screenshot 2024-02-06 at 8 55 21 PM

  2. Make sure the escape key to close menus works on mobile too. Low vision users who zoom in on desktop get the mobile menu.

  3. There was some oddities on the mobile nav on zoom to 200-400%. The Men's subnav didn't expand fully: Screenshot 2024-02-06 at 9 10 49 PM

I also couldn't get to the kid subnav either. Here's a video showing some of the behavior I was seeing.

I also had some challenges with scrolling in the mobile menu on mobile when the subnavs were open so worth checking the CSS.

It also would be good to open a separate issue for not allowing headers to be sticky on mobile. It blocks a lot of the content for zoomed-in low-vision users.

  1. The button/CTA is not in the nav tag: Screenshot 2024-02-06 at 9 14 00 PM

This is something that's outside the scope of this current GitHub issue, but I wanted to flag it for you. This is technically an accessibility error. The mega menu should support the ability to make the last item a button-styled link so that it can be in the nav tag. 😊

One other side note - I know this was just set up for testing, but if you all are creating templates that people can reuse, don't put H4s in there. The headings should either be H2s, or there should be a screen reader only H2 for the navigation and the headings in it should be H3s. It's important that this is set up properly in any kits or templates because a lot of users probably won't know to fix it. Maybe you need to have default font-sizes for H2 in the nav that are smaller?

I hope that's helpful. Let me know if you have more questions.

amberhinds avatar Feb 07 '24 03:02 amberhinds