Loading Developer Playground

Loading ...

Skip to main content
ARIA ROLEComposite RolesPersistent navigationHorizontal orientationKeyboard accelerators

menubar

A persistent horizontal menu of top-level choices that usually opens submenus. Think application menu bars (“File”, “Edit”, “View”).

Live Example

Global Menubar

Top-level menubar with nested menus, horizontal navigation, and Esc to close.

Purpose

Expose primary categories that open nested menus or dialogs.

Structure

Contains menuitem elements that may own role="menu" submenus.

Screen Reader

Announced as “menubar”. Users expect left/right arrows to move between top-level items.

When to Use

1

Desktop-style apps

Complex web apps mimicking desktop software (design tools, IDEs).

2

Persistent global nav

Sites needing strongly categorized command groups.

3

Shortcuts hub

Expose keyboard shortcuts and provide a predictable structure for advanced users.

Required Structure

Container

role="menubar" should include aria-label (e.g., “Editor commands”).

Menuitems

Top-level items use role="menuitem" and usually have tabindex="0" / -1 for roving focus.

Submenus

Use role="menu" for dropdown panes. Connect via aria-controls/aria-haspopup on the triggering menuitem.

Keyboard Interaction Model

ActionKeysResult
Move between top-level itemsArrowLeft / ArrowRightCycles focus through the menubar.
Open submenuArrowDown / Enter / SpaceOpens the submenu owned by the focused item.
Close submenuEscape / ArrowUpCloses submenu and returns focus to menubar item.
Jump to first/last itemHome / EndMoves focus to the first or last menubar item.
Mnemonic lettersCharacter keysMoves focus to the next item whose label starts with the typed letter.

Required States & Properties

aria-orientationOptional

Menubars are typically horizontal. Set explicitly to avoid ambiguity.

aria-haspopupOptional

Menuitems that open submenus must use aria-haspopup="menu" and manage aria-expanded.

aria-controlsOptional

Link menubar items to their submenu containers for assistive tech navigation.

aria-expandedOptional

Reflect whether its submenu is visible. Update as soon as menus open or close.

Implementation Checklist

  • Allow Alt + first letter or other accelerators if your user base expects them.

  • Keep the menubar visible at all times and ensure focus remains within the menu system when open.

  • Support wrapping navigation so Right from the last item returns to the first and vice versa.

  • When the page loses focus, close any open submenus to avoid stranded popups.

Code Examples

Menubar with Roving Focus

Each menuitem toggles aria-expanded when a submenu is available.

<nav role="menubar" aria-label="Editor commands">
  <button role="menuitem" aria-haspopup="menu" aria-controls="file-menu" aria-expanded="false">File</button>
  <button role="menuitem" aria-haspopup="menu" aria-controls="edit-menu" aria-expanded="false">Edit</button>
  <button role="menuitem" aria-haspopup="menu" aria-controls="view-menu" aria-expanded="false">View</button>
</nav>

Keyboard Manager

Simple logic to move focus between items.

const menubar = document.querySelector('[role="menubar"]')
const items = Array.from(menubar.querySelectorAll('[role="menuitem"]'))
let activeIndex = 0

function updateFocus(index) {
  items[activeIndex].tabIndex = -1
  activeIndex = index
  items[activeIndex].tabIndex = 0
  items[activeIndex].focus()
}

items.forEach((item, index) => {
  item.tabIndex = index === 0 ? 0 : -1
})

menubar.addEventListener('keydown', (event) => {
  if (event.key === 'ArrowRight') {
    event.preventDefault()
    updateFocus((activeIndex + 1) % items.length)
  } else if (event.key === 'ArrowLeft') {
    event.preventDefault()
    updateFocus((activeIndex - 1 + items.length) % items.length)
  }
})

Best Practices

🧭

Keep loops tight

Wrap navigation seamlessly so users never get trapped at the ends.

📎

Expose shortcuts

Include accelerators in labels (“Save ⌘S”) to help power users.

🌐

Touch + keyboard parity

Support tap/long-press for touch screens without breaking keyboard logic.

Common Mistakes

Using nav links

Anchors that navigate away instead of opening menus break the menubar paradigm.

Use buttons for menuitems and open submenus in-place.

Related Roles & Patterns

menu

Each menubar item often owns a menu.

Learn more

menuitem

Actionable descendant of menubar.

Learn more

menuitemradio

Exclusive options inside menus.

Learn more