menu
Marca un contenedor como menú de aplicación — el desplegable de menús al estilo Archivo/Edición o los menús contextuales. No existe equivalente HTML. Una lista de navegación del sitio NO es un menu; se debe usar <nav> con <ul> de enlaces.
Cuándo utilizarlo
Para un menú de tipo aplicación — el desplegable que aparece desde un botón «Archivo» o un menú contextual de clic derecho, con navegación por teclas de flecha y cierre mediante Escape. Los elementos secundarios deben tener role="menuitem", role="menuitemcheckbox", role="menuitemradio" o role="separator".
El rol menu corresponde a semántica de aplicación. El error más frecuente en la web es usar role="menu" para la navegación del sitio, lo que atrapa a los usuarios de teclado en una navegación por flechas, anuncia los enlaces incorrectamente como elementos de menú y rompe el modelo mental del usuario.
Regla general: si el activador es un hipervínculo y los elementos también son hipervínculos, se trata de navegación, no de un menú. Se debe usar <nav> y <ul>.
Un menu DEBE tener un nombre accesible: se empleará aria-label o aria-labelledby apuntando al activador.
Contrato de teclado y foco
Según el patrón de menú APG:
- El botón activador tiene
aria-haspopup="menu"yaria-expanded. Al activar el botón, el menú se abre y el foco se desplaza al primer menuitem. - Dentro del menú: las flechas Arriba/Abajo mueven el foco entre los elementos; Inicio/Fin saltan al primero/último.
- La flecha Derecha abre un submenú (si el elemento enfocado lo tiene); la flecha Izquierda vuelve al menú padre.
- Enter o Espacio activan el elemento enfocado y cierran el menú.
- Escape cierra el menú y devuelve el foco al activador.
- Escritura anticipada: escribir una letra salta al siguiente elemento que comienza por esa letra.
Tabulación única: solo un menuitem tiene tabindex="0" en cada momento; el resto tienen -1.
Fallos habituales
role="menu"sobre un elemento<nav>. La semántica de aplicación anula la semántica de navegación: los lectores de pantalla dejan de anunciarlo como punto de referencia de navegación.- Menú sin
aria-haspopup="menu"en su activador asociado. - Escape cierra el menú pero no devuelve el foco al activador, dejando al usuario desorientado.
- El foco NO se desplaza al primer menuitem al abrir el menú: el usuario debe tabular a través del vacío.
- Submenús que solo se abren al pasar el puntero, no mediante teclado.
Ejemplo
<button id="actions" aria-haspopup="menu" aria-expanded="false" aria-controls="actionsMenu">
Acciones
</button>
<ul id="actionsMenu" role="menu" aria-labelledby="actions" hidden>
<li role="menuitem" tabindex="0">Editar</li>
<li role="menuitem" tabindex="-1">Duplicar</li>
<li role="separator"></li>
<li role="menuitem" tabindex="-1">Eliminar</li>
</ul>