Skip to content

βœ… β™Ώ 🐞 Bug Report: Mega Menu Accessibility is not intuitiveΒ #23875

@Daveden2

Description

@Daveden2

Prerequisites

  • I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
  • 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).
  • This bug happens with a Blank WordPress theme active (Hello theme).
  • 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates a bug with one or multiple components.mod*[Temp.] For internal use only.mod/yr*[Temp.] For internal use only.product/proIndicates if the referenced component is part of the Elementor Pro plugin.solvedIndicates that an Issue has been Solved, or a Feature Request has been Released.status/mergedIndicates when a Pull Request has been merged to a Release.type/accessibilityIndicates when a topic is related to Accessibility.widget/nestedReferences any Nested widget and components.widget/nested/pro/menuReferences the (nested) (mega) Menu (Pro) widget.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions