Opened 5 years ago

Last modified 12 months ago

#4123 accepted defect (bug)

Proposal to improve the main navigation menu accessibility

Reported by: afercia's profile afercia Owned by: otto42's profile Otto42
Milestone: Priority: normal
Component: General Keywords: has-patch


Several HTML5 sectioning elements automatically create ARIA landmark regions.

Landmark regions are exposed to assistive technologies and allow users to quickly find information in a page. Ideally, all content in a web page should be wrapped within landmark regions. For now, I'd like to propose to focus on the navigation menu.

In this specific case it's important to know that <nav> elements are mapped to an ARIA role=navigation. Therefore, <nav> elements are perceived by screen readers and users can jump to them using dedicated keyboard shortcuts.

In the network, some sections don't use <nav> elements at all. For example, the home page (screenshot from Safari and VoiceOver):

Other sections do use navigation landmarks but not for the main menu. For example, the Themes section has two of them:

Same in the Plugin section sub-pages:

For clarity, these are respectively:

  • a <nav> element with a role="navigation": it was common practice to repeat the role even if redundant, to support old browsers assistive technologies
  • a <div> element with a role="navigation", which is equivalent to a <nav>

Besides technical details, the most important navigation (the main one) doesn't use a navigation landmark. Wrapping the main menu in a <nav> element would be a good, simple, improvement.

Note: when in a page there are multiple landmarks of the same type, it's important to use an aria-label to help users to distinguish them. This is also what WordPress core and the bundled themes do.


  • wrap the existing main menu markup in a <nav aria-label="Main menu">
  • where present, add to the secondary navigation an aria-label="Secondary menu" (or any better wording)
  • the toolbar already uses an aria-label="Toolbar", no need for any change


  • modernize the markup: remove role="navigation" and just use a <nav> element

Note about the wording:
When screen readers encounter a <nav> element or a role="navigation", they already announce "navigation": it's recommended to not use this word in the aria-label because it would be announced twice.

Change History (6)

#1 @Otto42
5 years ago

Okay, let's take these menus one at a time.

The main menu's markup:

<ul id="wporg-header-menu" class=" nav-menu">
<li class="menu-item">...

So, wrap a <nav aria-label="Main menu"> around this?

Similar for other menus, obviously, but is there any other markup changes that would be needed?

Converting it to a plain nav would require a more extensive change to the CSS (possibly on all subsites), but could be feasible.

Would it be preferable to use a role=navigation on the ul instead, to minimize the CSS adjustments?

#2 @Otto42
5 years ago

Oh, another question. Should the label be wrapped in a translation function as well? Like __('Main Menu','wporg'); I assume these labels should be translatable as they will be user facing in such readers.

#3 @afercia
5 years ago

It's recommended to not change the native semantics of the <ul>. Lists are announced as lists, together with the number of list items. That's good.

Yes, the <nav> should wrap the <ul>. Here's the W3C example (switch to the "HTML5 Techniques" tab): . The h2 is not necessary.

Yes, the aria-label should be translatable. Thank you.

#4 @Otto42
5 years ago

  • Owner set to Otto42
  • Status changed from new to accepted

#5 @Otto42
5 years ago

Added to global menu in [dotorg:14789].

This ticket was mentioned in PR #154 on WordPress/ by @nayanchamp7.

12 months ago

  • Keywords has-patch added

Trac ticket: #4123

### Proposal
<nav> elements are mapped to an ARIA role=navigation. Therefore, <nav> elements are perceived by screen readers and users can jump to them using dedicated keyboard shortcuts.

### Enhancement
area-label attribute is added into all the main header nav with relevant translation function for each project.

Note: See TracTickets for help on using tickets.