En este instructivo, se describe cómo crear una navegación principal accesible en un sitio web. Aprenderás sobre HTML semántico, accesibilidad y cómo el uso de atributos de ARIA a veces puede hacer más daño que bien.
Existen muchas formas diferentes de crear la navegación principal de un sitio web, en términos de diseño, funcionalidad y la información semántica y de marcado subyacente. Si la implementación es demasiado minimalista, funcionará para la mayoría de las personas, pero es posible que la experiencia del usuario (UX) no sea buena. Si tiene demasiado diseño, podría confundir a los usuarios o incluso impedirles poder acceder.
En la mayoría de los sitios web, lo ideal es crear algo que no sea ni demasiado simple ni demasiado complicado.
Compilación capa por capa
En este instructivo, comienzas con una configuración básica y agregas funciones capa por capa hasta un punto en el que proporcionas la cantidad justa de información, diseño y funcionalidad para satisfacer a la mayoría de los usuarios. Para lograrlo, debes usar el principio de mejora progresiva, que establece que debes comenzar con la solución más fundamental y sólida y agregar capas de funcionalidad de forma progresiva. Si una capa no funciona por algún motivo, la navegación seguirá funcionando porque se vuelve a la capa subyacente de forma fluida.
Estructura básica
Para una navegación básica, necesitas dos elementos: elementos <a>
y algunas líneas de CSS para mejorar el diseño y el estilo predeterminados de tus vínculos.
<a href="/home">Home</a>
<a href="/about-us">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Define variables for your colors */
:root {
--color-shades-dark: rgb(25, 25, 25);
}
/* Use the alternative box model
Details: <https://web.dev/learn/css/box-model/> */
*{
box-sizing: border-box;
}
/* Basic font styling */
body {
font-family: Segoe UI, system-ui, -apple-system, sans-serif;
font-size: 1.6rem;
}
/* Link styling */
a {
--text-color: var(--color-shades-dark);
border-block-end: 3px solid var(--border-color, transparent);
color: var(--text-color);
display: inline-block;
margin-block-end: 0.5rem; /* See note at the bottom of this chapter */
margin-inline-end: 0.5rem;
padding: 0.1rem;
text-decoration: none;
}
/* Change the border-color on :hover and :focus */
a:where(:hover, :focus) {
--border-color: var(--text-color);
}
Esto funciona bien para la mayoría de los usuarios, independientemente de cómo accedan al sitio. Se puede acceder a la navegación con un mouse, un teclado, un dispositivo táctil o un lector de pantalla, pero hay aspectos para mejorar. Puedes mejorar la experiencia extendiendo este patrón básico con información y funcionalidad adicionales.
Puedes hacer lo siguiente:
- Destaca la página activa.
- Anuncia la cantidad de elementos a los usuarios de lectores de pantalla.
- Agrega un punto de referencia y permite que los usuarios de lectores de pantalla accedan a la navegación directamente con un atajo.
- Oculta la navegación en viewports estrechos.
- Mejora el diseño del enfoque.
Destaca la página activa
Para destacar la página activa, puedes agregar una clase al vínculo correspondiente.
<a href="/about-us" class="active-page">About us</a>
El problema con este enfoque es que transmite la información qué vínculo está activo meramente visualmente. Un usuario ciego del lector de pantalla no podía distinguir la diferencia entre la página activa y otras páginas. Afortunadamente, el estándar de Aplicaciones web enriquecidas accesibles (ARIA) ofrece una forma de comunicar esta información de forma semántica. Usa el atributo y el valor aria-current="page" en lugar de una clase.
aria-current
(estado) indica el elemento que representa el elemento actual dentro de un contenedor o un conjunto de elementos relacionados.
Es un token de página que se usa para indicar un vínculo dentro de un conjunto de vínculos de paginación, en el que el vínculo tiene un diseño visual para representar la página que se muestra actualmente.
[Aplicaciones de Internet enriquecidas accesibles (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current)
Con el atributo adicional, un lector de pantalla ahora anuncia algo como "página actual, vínculo, Acerca de nosotros" en lugar de solo "vínculo, Acerca de nosotros".
<a href="/about-us" aria-current="page" class="active-page">About us</a>
Un efecto secundario conveniente es que puedes usar el atributo para seleccionar el vínculo activo en CSS, lo que hace que la clase active-page
quede obsoleta.
<a href="/home">Home</a>
<a href="/about-us" aria-current="page">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Change border-color and color for the active page */
[aria-current="page"] {
--border-color: var(--color-highlight);
--text-color: var(--color-highlight);
}
Anuncia la cantidad de elementos
Cuando observan la navegación, los usuarios videntes pueden saber que solo contiene cuatro vínculos. Un usuario ciego de lector de pantalla no puede obtener esta información con tanta rapidez. Es posible que deba revisar toda la lista de vínculos. Esto puede no ser un problema si la lista es corta, como en este ejemplo, pero si contiene 40 vínculos, esta tarea puede ser engorrosa. Si un usuario de lector de pantalla sabe de antemano que la navegación contiene muchos vínculos, es posible que decida usar una forma de navegación diferente y más eficiente, como la búsqueda del sitio.
Una buena manera de comunicar la cantidad de elementos de antemano es unir cada vínculo en un elemento de lista (<li>
), anidado en una lista desordenada (<ul>
).
<ul>
<li>
<a href="/home">Home</a>
</li>
<li>
<a href="/about-us" aria-current="page">About us</a>
</li>
<li>
<a href="/pricing">Pricing</a>
</li>
<li>
<a href="/contact">Contact</a>
</li>
</ul>
Cuando un usuario de lector de pantalla encuentre la lista, su software anunciará algo como "lista, 4 elementos".
Esta es una demostración de la navegación que se usa con el lector de pantalla NVDA en Windows.
Ahora debes adaptar el diseño para que se vea como antes.
/* Remove the default list styling and create a flexible layout for the list */
ul {
display: flex;
flex-wrap: wrap;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
/* Basic link styling */
a {
--text-color: var(--color-shades-dark);
border-block-end: 3px solid var(--border-color, transparent);
color: var(--text-color);
padding: 0.1rem;
text-decoration: none;
}
Usar listas puede tener muchas ventajas para los usuarios de lectores de pantalla:
- Pueden obtener la cantidad total de elementos antes de interactuar con ellos.
- Pueden usar atajos para saltar de un elemento de la lista a otro.
- Pueden usar combinaciones de teclas para pasar de una lista a otra.
- Es posible que el lector de pantalla anuncie el índice del elemento actual (por ejemplo, “elemento de lista, dos de cuatro”).
Además, si la página se presenta sin CSS, la lista muestra los vínculos como un grupo coherente de elementos en lugar de solo una pila de vínculos.
Un detalle notable sobre VoiceOver en Safari es que pierdes todas estas ventajas cuando configuras list-style: none
. Se diseñó de este modo. El equipo de WebKit decidió quitar la semántica de lista cuando una lista no parece una. Según la complejidad de tu navegación, esto puede o no ser un problema. Por un lado, la navegación sigue siendo utilizable y solo afecta a VoiceOver en Safari. VoiceOver con Chrome o Firefox sigue anunciando la cantidad de elementos, al igual que otros lectores de pantalla, como NVDA. Por otro lado, la información semántica puede ser muy útil en algunas situaciones. Para tomar esa decisión, debes probar la navegación con usuarios reales de lectores de pantalla y obtener sus comentarios. Si decides que necesitas que VoiceOver en Safari se comporte como todos los demás lectores de pantalla, puedes configurar el rol de lista de ARIA de forma explícita en <ul>
para solucionar el problema. Esto revertirá el comportamiento al estado anterior a quitar el diseño de la lista. Visualmente, la lista sigue siendo igual.
<ul role="list">
<li>
<a href="/home">Home</a>
</li>
...
</ul>
Agregar un punto de referencia
Con poco esfuerzo, realizaste grandes mejoras para los usuarios de lectores de pantalla, pero hay una cosa más que puedes hacer. La navegación es semánticamente solo una lista de vínculos, y es difícil saber que esta lista específica es la navegación principal de tu sitio web. Para convertir esta lista ordinaria en una lista de navegación, une el <ul>
en un elemento <nav>
.
El uso del elemento <nav>
tiene varias ventajas. En particular, un lector de pantalla anuncia algo como "navegación" cuando el usuario interactúa con él y agrega un punto de referencia a la página. Los puntos de referencia son regiones especiales de la página, como <header>
, <footer>
o <main>
, a las que puede saltar un lector de pantalla. Tener puntos de referencia en una página puede ser útil, ya que permite que los usuarios de lectores de pantalla accedan directamente a regiones importantes de la página sin tener que interactuar con el resto de la página. Por ejemplo, puedes presionar la tecla D en NVDA para saltar de un punto de referencia a otro. En VoiceOver, puedes usar el rotor para mostrar una lista de todos los puntos de referencia de la página. Para ello, presiona VO + U.
En esta lista, se muestran 4 puntos de referencia: banner, que es el elemento <header>
, navegación, que es <nav>
, principal, que es el elemento <main>
, y información del contenido, que es <footer>
. Esta lista no debe ser demasiado larga, ya que solo debes marcar partes fundamentales de tu IU como puntos de referencia, como la búsqueda del sitio, una navegación local o una paginación.
Si tienes una navegación en todo el sitio, una navegación local para la página y una paginación en una sola página, es posible que también tengas 3 elementos <nav>
. Está bien, pero ahora hay tres puntos de referencia de navegación y, semánticamente, todos se ven iguales. Es difícil diferenciarlos, a menos que conozcas muy bien la estructura de la página.
Para que se puedan distinguir, debes etiquetarlos con aria-labelledby
o aria-label
.
<nav aria-label="Main">
<ul>
<li>
<a href="/home">Home</a>
</li>
...
</ul>
</nav>
...
<nav aria-label="Select page">
<ul>
<li>
<a href="/page-1">1</a>
</li>
...
</ul>
</nav>
Si la etiqueta que elegiste ya existe en algún lugar de la página, puedes usar aria-labelledby
y hacer referencia a la etiqueta existente con el atributo id
.
<nav aria-labelledby="pagination_heading">
<h2 id="pagination_heading">Select a page</h2>
<ul>
<li>
<a href="/page-1">1</a>
</li>
...
</ul>
</nav>
Una etiqueta concisa es suficiente, no te extiendas demasiado. Omite expresiones como “navegación” o “menú” porque el lector de pantalla ya proporciona esta información a los usuarios.
Cómo ocultar la navegación en viewports estrechos
Personalmente, no me gusta ocultar la navegación principal en viewports estrechos, pero si la lista de vínculos es demasiado larga, no hay forma de evitarlo. Si ese es el caso, en lugar de la lista, los usuarios ven un botón etiquetado como "Menú", un ícono de hamburguesa o una combinación. Cuando haces clic en el botón, se muestra y se oculta la lista. Si conoces JavaScript y CSS básicos, es una tarea factible, pero debes tener en cuenta varios aspectos en términos de UX y accesibilidad.
- Debes ocultar la lista de forma accesible.
- La navegación debe ser accesible con el teclado.
- La navegación debe comunicar si es visible o no.
Cómo agregar un botón de opciones
Como sigues el principio de mejora progresiva, debes asegurarte de que tu navegación siga funcionando y tenga sentido incluso con JavaScript desactivado.
Lo primero que necesita tu navegación es un botón de opciones. Se crea en HTML en un elemento de plantilla, se clona en JavaScript y se agrega a la navegación.
<nav id="mainnav">
...
</nav>
<template id="burger-template">
<button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
<svg width="24" height="24" aria-hidden="true">
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
</svg>
</button>
</template>
- El atributo
aria-expanded
le indica al software del lector de pantalla si el elemento que controla el botón está expandido o no. aria-label
le da al botón un nombre de accesibilidad, una alternativa de texto para el ícono de hamburguesa.- Ocultas el
<svg>
de la tecnología de accesibilidad conaria-hidden
porque ya tiene una etiqueta de texto proporcionada poraria-label
. aria-controls
le indica a la tecnología de accesibilidad, que admite el atributo (por ejemplo, JAWS), qué elemento controla el botón.
const nav = document.querySelector('#mainnav')
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const button = burgerClone.querySelector('button');
// Toggle aria-expanded attribute
button.addEventListener('click', e => {
// aria-expanded="true" signals that the menu is currently open
const isOpen = button.getAttribute('aria-expanded') === "true"
button.setAttribute('aria-expanded', !isOpen);
});
// Hide list on keydown Escape
nav.addEventListener('keyup', e => {
if (e.code === 'Escape') {
button.setAttribute('aria-expanded', false);
}
});
// Add the button to the page
nav.insertBefore(burgerClone, list);
- Es conveniente que los usuarios puedan cerrar la navegación cuando quieran, por ejemplo, presionando la tecla Escape.
- Es importante usar
insertBefore
en lugar deappendChild
porque el botón debe ser el primer elemento de tu navegación. Si un usuario de teclado o lector de pantalla presiona Tab después de hacer clic en el botón, espera enfocar el primer elemento de la lista. Si el botón aparece después de la lista, no sería así.
A continuación, restableces el diseño predeterminado del botón y te aseguras de que solo sea visible en viewports estrechos.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
}
}
/* Reset button styling */
button {
all: unset;
display: var(--nav-button-display, flex);
}
Cómo ocultar la lista
Antes de ocultar la lista, posiciona y aplica diseño a la navegación y la lista para que el diseño se optimice para viewports estrechos, pero que aún se vea bien en pantallas más grandes.
Primero, quita el <nav>
del flujo natural de la página y colócalo en la esquina superior del viewport.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
}
nav {
position: var(--nav-position, fixed);
inset-block-start: 1rem;
inset-inline-end: 1rem;
}
A continuación, cambia el diseño en viewports estrechos agregando una nueva propiedad personalizada (—-nav-list-layout)
. El diseño es de columna de forma predeterminada y cambia a fila en pantallas más grandes.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
ul {
--nav-list-layout: row;
}
}
ul {
display: flex;
flex-direction: var(--nav-list-layout, column);
flex-wrap: wrap;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
La navegación debería verse de la siguiente manera en viewports estrechos.
Es evidente que la lista necesita CSS. Lo moveremos hasta la esquina superior, haremos que ocupe toda la pantalla verticalmente y aplicaremos un background-color
y un box-shadow
.
@media (min-width: 48em) {
nav {
--nav-button-display: none;
--nav-position: static;
}
ul {
--nav-list-layout: row;
--nav-list-position: static;
--nav-list-padding: 0;
--nav-list-height: auto;
--nav-list-width: 100%;
--nav-list-shadow: none;
}
}
ul {
background: rgb(255, 255, 255);
box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
display: flex;
flex-direction: var(--nav-list-layout, column);
flex-wrap: wrap;
gap: 1rem;
height: var(--nav-list-height, 100vh);
list-style: none;
margin: 0;
padding: var(--nav-list-padding, 2rem);
position: var(--nav-list-position, fixed);
inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
width: var(--nav-list-width, min(22rem, 100vw));
}
button {
all: unset;
display: var(--nav-button-display, flex);
position: relative;
z-index: 1;
}
La lista debería verse de la siguiente manera en viewports estrechos, más como una barra lateral que como una lista simple.
Por último, oculta la lista, muéstrala solo cuando el usuario haga clic en el botón una vez y vuelve a ocultarla cuando vuelva a hacer clic. Es importante ocultar solo la lista y no toda la navegación, ya que ocultarla también implicaría ocultar un punto de referencia importante.
Antes, agregaste un evento de clic al botón para activar o desactivar el valor del atributo aria-expanded
. Puedes usar esa información como condición para mostrar y ocultar la lista en CSS.
@media (min-width: 48em) {
ul {
--nav-list-visibility: visible;
}
}
ul {
visibility: var(--nav-list-visibility, visible);
}
/* Hide the list on narrow viewports, if it comes after an element with
aria-expanded set to "false". */
[aria-expanded="false"] + ul {
visibility: var(--nav-list-visibility, hidden);
}
Es importante usar una declaración de propiedad como visibility: hidden
o display: none
, en lugar de opacity: 0
o translateX(100%)
, para ocultar la lista. Estas propiedades se aseguran de que los vínculos no se puedan enfocar cuando la navegación está oculta. Si usas opacity
o translate
, se quitará el contenido visualmente, por lo que los vínculos serán invisibles, pero se podrá acceder a ellos con el teclado, lo que sería confuso y frustrante. El uso de visibility
o display
lo oculta visualmente y lo hace inaccesible, por lo que se oculta para todos los usuarios.
Animación de la lista
Si te preguntas por qué usar visibility: hidden;
en lugar de display: none;
, es porque puedes animar la visibilidad. Solo tiene dos estados, hidden
y visible
, pero puedes combinarlo con otra propiedad, como transform
o opacity
, para crear un efecto de deslizamiento o fundido de entrada. Eso no funcionaría con display: none porque la propiedad display no se puede animar.
Las siguientes transiciones de CSS opacity
crean un efecto de atenuación.
ul {
transition: opacity 0.6s linear, visibility 0.3s linear;
visibility: var(--nav-list-visibility, visible);
}
[aria-expanded="false"] + ul {
opacity: 0;
visibility: var(--nav-list-visibility, hidden);
}
En cambio, si deseas animar el movimiento, deberías considerar unir la propiedad transition
en una consulta de medios prefers-reduced-motion porque las animaciones pueden provocar náuseas, mareos y dolores de cabeza en algunos usuarios.
ul {
visibility: var(--nav-list-visibility, visible);
}
@media (prefers-reduced-motion: no-preference) {
ul {
transition: transform 0.6s cubic-bezier(.68,-0.55,.27,1.55), visibility 0.3s linear;
}
}
[aria-expanded="false"] + ul {
transform: var(--nav-list-transform, translateX(100%));
visibility: var(--nav-list-visibility, hidden);
}
De este modo, se garantiza que solo las personas que no tienen preferencia por el movimiento reducido vean la animación.
Mejora el diseño del enfoque
Los usuarios de teclado dependen de los estilos de enfoque de los elementos para la orientación y la navegación en una página. Los estilos de enfoque predeterminados son mejores que no tener estilos de enfoque (lo que sucede si configuras outline: none
), pero tener estilos de enfoque personalizados más visibles mejora la experiencia del usuario.
Así es como se ven los estilos de enfoque predeterminados en el vínculo en Chrome 103.
Puedes mejorarlo proporcionando tus propios estilos en tus propios colores. Cuando usas :focus-visible
en lugar de :focus
, permites que el navegador decida cuándo es apropiado mostrar los estilos de enfoque. Los estilos de :focus
estarán visibles para todos los usuarios (mouse, teclado y táctil), independientemente de si los necesitan o no. Con :focus-visible
, el navegador usa heurísticas internas para decidir si mostrarlas solo a los usuarios del teclado o a todos.
/* Remove the default :focus outline */
*:focus {
outline: none;
}
/* Show a custom outline on :focus-visible */
*:focus-visible {
outline: 2px solid var(--color-shades-dark);
outline-offset: 4px;
}
Compatibilidad del navegador con :focus-visible
Existen diferentes formas de destacar elementos cuando están enfocados. Se recomienda usar la propiedad outline
porque no rompe el diseño, lo que podría suceder con border
, y funciona bien con el modo de contraste alto en Windows. Las propiedades que no funcionan bien son background-color
o box-shadow
, ya que es posible que no se muestren en absoluto con la configuración de contraste personalizada.
¡Felicitaciones! Creaste una navegación principal mejorada de forma progresiva, semánticamente rica, accesible y optimizada para dispositivos móviles.
Siempre hay algo que se puede mejorar, por ejemplo:
- Puedes capturar el enfoque dentro de la navegación o hacer que el resto de la página sea inerte en viewports estrechos.
- Puedes agregar un vínculo de navegación en la parte superior de la página para permitir que los usuarios del teclado omitan la navegación.
Si recuerdas cómo comenzó este artículo, con el objetivo de que la solución no fuera “ni demasiado simple ni demasiado complicada”, ahí es donde estamos ahora. Sin embargo, es posible sobreingeniería una navegación.
Navegaciones en comparación con menús
Hay una clara diferencia entre la navegación y los menús. Las navegaciones son colecciones de vínculos para navegar por documentos relacionados. Los menús son colecciones de acciones que se pueden realizar en un documento. A veces, estas tareas se superponen. Puedes tener una navegación que también incluya un botón que realice una acción, como abrir una ventana modal, o bien un menú en el que una acción navegue a otra página, como una página de ayuda. Cuando ese sea el caso, es importante que no combines los roles de ARIA, sino que identifiques el objetivo principal de tu componente y elijas el lenguaje de marcado y los roles según corresponda.
El elemento <nav>
tiene un rol ARIA implícito de navegación que es suficiente para comunicar que el elemento es un elemento de navegación, pero a menudo se ve que los sitios también usan menu, menubar y menuitem. Dado que a veces usamos estos términos de forma indistinta, pensar que combinarlos para mejorar la experiencia de los usuarios de lectores de pantalla podría tener sentido. Antes de aprender por qué no suele ser el caso, veamos la definición oficial de estos roles.
El rol de navegación
Es una colección de elementos de navegación (por lo general, vínculos) para navegar por el documento o los documentos relacionados.
navigation (role) WAI-ARIA 1.1
El rol del menú
A menudo, un menú es una lista de acciones o funciones comunes que el usuario puede invocar. El rol del menú es adecuado cuando una lista de elementos del menú se presenta de manera similar a un menú en una aplicación de escritorio.
menú (rol) WAI-ARIA 1.1
El rol de la barra de menú
Es una presentación de menú que suele permanecer visible y que se presenta de forma horizontal. El rol de la barra de menú se usa para crear una barra de menú similar a las que se encuentran en las aplicaciones de escritorio de Windows, Mac y Gnome. Se usa una barra de menú para crear un conjunto coherente de comandos de uso frecuente. Los autores deben asegurarse de que la interacción de la barra de menú sea similar a la interacción típica de la barra de menú en una interfaz gráfica de usuario de escritorio.
menubar (role) WAI-ARIA 1.1
El rol de elemento de menú
Es una opción en un conjunto de opciones que se incluyen en un menú o una barra de menú.
menuitem (role) WAI-ARIA 1.1
La especificación es muy clara aquí, usa la navegación para navegar por el documento o los documentos relacionados, y el menú solo para una lista de acciones o funciones similares a los menús de las aplicaciones para computadoras de escritorio. Si no estás creando el próximo documento de Google, es probable que no necesites ninguno de los roles del menú para la navegación principal.
¿Cuándo es apropiado usar un menú?
El uso principal de los elementos del menú no es la navegación, sino la realización de acciones. Supongamos que tienes una lista o una tabla de datos y los usuarios pueden realizar ciertas acciones en cada elemento de la lista. Puedes agregar un botón a cada fila y mostrar las acciones cuando los usuarios hagan clic en él.
<ul>
<li>
Product 1
<button aria-expanded="false" aria-controls="options1">Edit</button>
<div role="menu" id="options1">
<button role="menuitem">
Duplicate
</button>
<button role="menuitem">
Delete
</button>
<button role="menuitem">
Disable
</button>
</div>
</li>
<li>
Product 2
...
</li>
</ul>
Implicaciones de usar los roles del menú
Es muy importante usar estos roles de menú con prudencia, ya que pueden ocurrir muchos errores.
Los menús esperan una estructura DOM determinada. menuitem
debe ser un elemento secundario directo de menu
. El siguiente código podría romper el comportamiento semántico:
<!-- Wrong, don't do this -->
<ul role="menu">
<li>
<a href="#" role="menuitem">Item 1</a>
</li>
</ul>
Los usuarios expertos esperan que ciertas combinaciones de teclas funcionen con menús y barras de menú. Según la Guía de prácticas de creación de ARIA (APG), esto incluye lo siguiente:
- Intro y la barra espaciadora para seleccionar elementos del menú.
- Teclas de flecha en todas las direcciones para navegar entre los elementos.
- Las teclas Inicio y Fin para mover el enfoque al primer o último elemento, respectivamente.
- a-z para mover el foco al siguiente elemento de menú con una etiqueta que comienza con el carácter escrito.
- Esc para cerrar el menú.
Si un lector de pantalla detecta un menú, el software puede cambiar automáticamente el modo de navegación, lo que habilita el uso de las combinaciones de teclas mencionadas anteriormente. Es posible que los usuarios sin experiencia en lectores de pantalla no puedan usar el menú porque no conocen estas combinaciones de teclas ni cómo usarlas.
Lo mismo sucede con los usuarios de teclado que podrían esperar que puedan usar Mayúsculas y Mayúsculas + Tab.
Hay muchos aspectos que debes tener en cuenta cuando creas menús y barras de menú, y lo primero que debes determinar es si es apropiado usarlos. Cuando creas un sitio web típico, lo único que necesitas es el elemento de navegación con una lista y vínculos. Esto también incluye aplicaciones web o de una sola página (SPA). La pila subyacente no importa. A menos que estés compilando algo muy similar a una aplicación para computadoras de escritorio, evita los roles de menú.
Recursos adicionales
- Corrección de listas de Scott O'hara.
- Don't Use ARIA Menu Roles for Site Nav, de Adrian Roselli
- Menús y botones de menú, de Heydon Pickering.
- WAI-ARIA menus, and why you should handle them with great care, de Marco Zehe.
- Ocultar contenido de forma responsable, de Kitty Giraudel.
- :focus-visible Is Here de Matthias Ott.
Hero image de Mick Haupt