Menubar
Barra de menú de aplicación con submenús y navegación completa por teclado. Solo para menús de comandos complejos, no para navegación web.
1. Menubar básico (Archivo / Editar / Ver)
Mostrar HTML
<div class="gn-menubar" role="menubar" aria-label="Menú de aplicación">
<div class="gn-menubar__item">
<button type="button" class="gn-menubar__trigger" role="menuitem" aria-haspopup="true" aria-expanded="false" aria-controls="mb1-archivo" tabindex="0">
Archivo
<svg class="gn-menubar__chevron" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 8"><path d="M12 1.0752L6 7.0752L0 1.0752L1.0752 0L6 4.9248L10.9248 0L12 1.0752Z"/></svg>
</button>
<ul id="mb1-archivo" class="gn-menubar__menu" role="menu" aria-label="Archivo" hidden>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Nuevo</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Abrir</button></li>
<li role="none"><div class="gn-menubar__menu-separator" role="separator"></div></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Guardar</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Guardar como…</button></li>
</ul>
</div>
<div class="gn-menubar__item">
<button type="button" class="gn-menubar__trigger" role="menuitem" aria-haspopup="true" aria-expanded="false" aria-controls="mb1-editar" tabindex="-1">
Editar
<svg class="gn-menubar__chevron" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 8"><path d="M12 1.0752L6 7.0752L0 1.0752L1.0752 0L6 4.9248L10.9248 0L12 1.0752Z"/></svg>
</button>
<ul id="mb1-editar" class="gn-menubar__menu" role="menu" aria-label="Editar" hidden>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Deshacer</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Rehacer</button></li>
<li role="none"><div class="gn-menubar__menu-separator" role="separator"></div></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Cortar</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Copiar</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Pegar</button></li>
</ul>
</div>
<div class="gn-menubar__item">
<button type="button" class="gn-menubar__trigger" role="menuitem" aria-haspopup="true" aria-expanded="false" aria-controls="mb1-ver" tabindex="-1">
Ver
<svg class="gn-menubar__chevron" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 8"><path d="M12 1.0752L6 7.0752L0 1.0752L1.0752 0L6 4.9248L10.9248 0L12 1.0752Z"/></svg>
</button>
<ul id="mb1-ver" class="gn-menubar__menu" role="menu" aria-label="Ver" hidden>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Acercar</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Alejar</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Restablecer vista</button></li>
</ul>
</div>
</div>
Mostrar JS
document.addEventListener('DOMContentLoaded', () => {
window.GNDS.initMenubars();
});
2. Menubar con item sin submenú
Mostrar HTML
<div class="gn-menubar" role="menubar" aria-label="Herramientas del editor">
<div class="gn-menubar__item">
<button type="button" class="gn-menubar__trigger" role="menuitem" aria-haspopup="true" aria-expanded="false" aria-controls="mb2-formato" tabindex="0">
Formato
<svg class="gn-menubar__chevron" aria-hidden="true" focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 8"><path d="M12 1.0752L6 7.0752L0 1.0752L1.0752 0L6 4.9248L10.9248 0L12 1.0752Z"/></svg>
</button>
<ul id="mb2-formato" class="gn-menubar__menu" role="menu" aria-label="Formato" hidden>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Negrita</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Cursiva</button></li>
<li class="gn-menubar__menuitem-wrapper" role="none"><button type="button" class="gn-menubar__menuitem" role="menuitem">Subrayado</button></li>
</ul>
</div>
<div class="gn-menubar__item">
<button type="button" class="gn-menubar__trigger" role="menuitem" tabindex="-1">
Ayuda
</button>
</div>
</div>
Mostrar JS
document.addEventListener('DOMContentLoaded', () => {
window.GNDS.initMenubars();
});
gn-menubar es una barra de menú de aplicación con submenús y navegación completa por teclado. No es para navegación web: usar gn-navmenu para la navegación principal de un sitio.
Cuándo usar menubar
Solo cuando se construye una interfaz de tipo aplicación con comandos complejos organizados en menús jerárquicos. Ejemplos válidos: Archivo / Editar / Ver / Herramientas; un editor de contenido con formato, inserción e historial.
No usar menubar para la navegación principal de un sitio web, filtros, ni agrupaciones de acciones simples (para eso usar gn-toolbar o gn-dropdown-menu).
Diferencia con navmenu
gn-navmenu usa <nav> semántico y sus ítems representan destinos de navegación. gn-menubar usa role="menubar" y sus ítems representan comandos de aplicación. Esta distinción es crítica para tecnologías asistivas: un lector de pantalla anuncia las diferencias entre "menú de aplicación" y "navegación".
Estructura ARIA
El contenedor usa role="menubar" con aria-label obligatorio. Cada ítem que abre un submenú usa role="menuitem" con aria-haspopup="true" y aria-expanded. Los submenús usan role="menu". Cada opción dentro del submenú usa role="menuitem".
Los elementos <li> contenedores de cada opción deben tener role="none" para no introducir semántica de lista redundante.
Comportamiento de teclado
Nivel superior (menubar):
Tabentra al menubar; solo un ítem tienetabindex="0"(roving tabindex).ArrowRight/ArrowLeftmueve el foco entre los ítems del menubar (con loop).ArrowDownoEnter/Spaceabren el submenú y mueven el foco al primer menuitem.ArrowUpabre el submenú y mueve el foco al último menuitem.Home/Endmueven al primer o último ítem del menubar.Escapecierra cualquier submenú abierto.
Dentro de un submenú (menu):
ArrowDown/ArrowUpmueven el foco entre menuitems (con loop).Home/Endmueven al primer o último menuitem.Enter/Spaceejecutan el menuitem y cierran el menú.EscapeoArrowLeftcierran el submenú y devuelven el foco al ítem padre.ArrowRightcierra el submenú actual y abre el siguiente ítem del menubar.Tabcierra todos los submenús y mueve el foco fuera del menubar.
Responsabilidad ARIA
No declarar role="menubar" sin implementar la navegación de teclado completa. Un menubar sin navegación con flechas no cumple las expectativas de los usuarios de teclado y lectores de pantalla, y puede resultar más confuso que una solución más simple.