Addaw, ir a inicio Donar

Lección 4 de 10 · 10 min de lectura · Revisado el 26/10/2026

Roles, estados y propiedades; nombre y descripción accesibles (4.1.2)

El criterio 4.1.2 Nombre, función, valor (A) es el corazón de la accesibilidad de cualquier componente: para todo elemento de interfaz, el nombre y la función (rol) deben poder determinarse por programa; los estados, propiedades y valores que la persona puede modificar deben poder leerse y cambiarse por programa; y las tecnologías de apoyo deben ser notificadas de los cambios. ARIA es el vocabulario con el que expresamos todo eso cuando HTML no llega. En esta lección ordenamos ese vocabulario.

Roles: qué es el elemento

El rol responde a la pregunta «¿qué es esto?». ARIA 1.2 define decenas de roles agrupados en categorías:

  • Roles de widget: button, checkbox, radio, switch, slider, tab, menuitem, option, combobox, textbox, link…
  • Roles compuestos, que contienen widgets: tablist, menu, listbox, radiogroup, tree, grid.
  • Roles de estructura: heading (con aria-level), list, listitem, table, row, cell, img, group, presentation/none.
  • Roles de landmark: banner, navigation, main, complementary, contentinfo, search, form, region.
  • Roles de región activa: alert, status, log, timer, marquee.
  • Roles de ventana: dialog, alertdialog.

Casi todos tienen un equivalente HTML con rol implícito (<button> es button, <h2> es heading nivel 2, <nav> es navigation). Escribir el rol explícito sobre el elemento nativo equivalente (<button role="button">) es redundante e inútil; las herramientas lo marcan como aviso.

Algunos roles exigen una estructura concreta: un tab debe estar dentro de un tablist; un option, dentro de un listbox; un row, dentro de un table o grid; un menuitem, dentro de un menu o menubar. Si rompes esa jerarquía, el lector no sabe interpretar el componente.

Estados y propiedades: cómo está y con qué se relaciona

Los atributos aria-* se dividen en dos grupos. Los estados cambian con la interacción y hay que actualizarlos con JavaScript:

EstadoSignificadoDónde se usa
aria-expandedDesplegado o contraídoBotones de acordeón, menús, combobox
aria-pressedPulsado o no (conmutador)Botones de alternancia (negrita, favorito)
aria-checkedMarcado, no marcado o mixtoCasillas y radios personalizados, switch
aria-selectedSeleccionadoPestañas, opciones, filas de rejilla
aria-disabledDeshabilitado pero perceptibleControles personalizados
aria-invalidValor no válidoCampos con error
aria-currentElemento actual de un conjuntoEnlace de la página actual, paso actual
aria-busySe está actualizandoRegiones en carga

Las propiedades describen características y relaciones más estables:

  • Nombrado y descripción: aria-label, aria-labelledby, aria-describedby.
  • Relaciones: aria-controls (qué elemento controla), aria-owns (hijos lógicos fuera del DOM), aria-activedescendant (qué descendiente tiene el foco virtual).
  • Rango y valor: aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext para deslizadores, barras de progreso y medidores.
  • Comportamiento: aria-haspopup, aria-modal, aria-multiselectable, aria-required, aria-readonly, aria-level, aria-posinset, aria-setsize.
  • Visibilidad: aria-hidden (que WAI-ARIA 1.2 (se abre en una ventana nueva) clasifica, en realidad, como estado).

Ejemplo

Un interruptor de «Notificaciones» construido con un botón nativo:

<button type="button" role="switch" aria-checked="false" id="notif">
  Notificaciones por correo
</button>
const sw = document.getElementById('notif');
sw.addEventListener('click', () => {
  const activo = sw.getAttribute('aria-checked') === 'true';
  sw.setAttribute('aria-checked', String(!activo));
});

El lector anuncia «Notificaciones por correo, interruptor, desactivado» y, al pulsar, «activado». Se cumple 4.1.2: nombre (el texto), función (switch), estado (aria-checked) y notificación del cambio (el navegador avisa al cambiar el atributo). El teclado lo da el <button>. El estilo visual del interruptor se dibuja con CSS a partir de [aria-checked="true"], de modo que estado visual y programático nunca se separan.

Nombre y descripción accesibles

Recordemos del curso de HTML el orden de cálculo del nombre: aria-labelledby, aria-label, fuente nativa, title. Añadimos ahora matices importantes:

  • aria-labelledby puede referenciar varios id y los concatena en orden, incluido el propio elemento. Es útil para componer nombres: aria-labelledby="boton-leer titulo-tarjeta" da «Leer más Presupuestos 2025»; si inviertes el orden de los id, el nombre será «Presupuestos 2025 Leer más».
  • El elemento referenciado puede estar oculto con hidden o aria-hidden; su texto se usa igual para el nombre. Eso permite textos solo para el nombre sin mostrarlos.
  • aria-label y aria-labelledby no funcionan de forma fiable en elementos sin rol o con roles genéricos (div, span) ni en algunos roles de texto, como paragraph (el de p), code o strong, que prohíben expresamente el nombre. Poner aria-label en un <div> sin rol no sirve para nada en la práctica.
  • La descripción (aria-describedby) es información secundaria: el lector la anuncia después del nombre, el rol y el estado, a menudo tras una pausa, y algunos usuarios la desactivan. Nunca pongas en la descripción algo imprescindible para entender el control.
  • Los roles de widget solo admiten nombre a partir del contenido en algunos casos (button, link, tab, menuitem, option, checkbox…). Un textbox, combobox o slider necesita aria-label, aria-labelledby o un <label>.

Error frecuente

<div aria-label="Resultados de la búsqueda">…</div>
<span aria-label="Precio">189 €</span>

En el primer caso el aria-label se ignora porque el <div> no tiene rol; hace falta role="region" (o un <section>). En el segundo, en algunos navegadores el nombre sustituye al contenido y la persona oye «Precio» pero no «189 €». Para texto normal, no uses aria-label; escribe el texto visible que haga falta.

Notificar los cambios

La última parte de 4.1.2 dice que las tecnologías de apoyo deben ser notificadas de los cambios de estado. Esto ocurre automáticamente cuando modificas los atributos ARIA o las propiedades nativas (checked, disabled, value) del elemento que tiene el foco: el navegador genera el evento de accesibilidad correspondiente. Lo que no se notifica es un cambio puramente visual: cambiar una clase CSS para pintar un botón como «activo» sin tocar aria-pressed deja al lector sin información. La regla es sencilla: cada estado visual debe tener un estado programático que lo acompañe, y lo ideal es que el CSS dependa del atributo ([aria-pressed="true"]) y no de una clase paralela.

Punto clave

Para cada componente pregunta cuatro cosas: ¿qué es? (rol), ¿cómo se llama? (nombre), ¿cómo está? (estado o valor) y ¿se entera el lector cuando cambia? Si las cuatro tienen respuesta en el código, cumples 4.1.2.

Resumen

  • El rol dice qué es el elemento; casi siempre lo aporta el HTML nativo, y los roles explícitos deben respetar la jerarquía que exige ARIA.
  • Los estados (aria-expanded, aria-checked, aria-selected, aria-current…) cambian con la interacción y deben actualizarse con JavaScript; las propiedades describen relaciones y rangos.
  • aria-label y aria-labelledby solo funcionan en elementos con rol; no los uses en texto normal.
  • La descripción es secundaria; lo imprescindible va en el nombre o en el contenido.
  • Haz que el CSS dependa del atributo ARIA para que estado visual y programático nunca se separen.

Comprueba lo que has aprendido

Esta lección se puede leer libremente. Para hacer su test de 3 preguntas, los ejercicios prácticos con páginas reales, guardar tu avance y optar al examen y al certificado, matricúlate en el curso.