Normativas · ARIA

Rol Control compuesto

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" y aria-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>