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(conaria-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:
| Estado | Significado | Dónde se usa |
|---|---|---|
aria-expanded | Desplegado o contraído | Botones de acordeón, menús, combobox |
aria-pressed | Pulsado o no (conmutador) | Botones de alternancia (negrita, favorito) |
aria-checked | Marcado, no marcado o mixto | Casillas y radios personalizados, switch |
aria-selected | Seleccionado | Pestañas, opciones, filas de rejilla |
aria-disabled | Deshabilitado pero perceptible | Controles personalizados |
aria-invalid | Valor no válido | Campos con error |
aria-current | Elemento actual de un conjunto | Enlace de la página actual, paso actual |
aria-busy | Se está actualizando | Regiones 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-valuetextpara 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-labelledbypuede referenciar variosidy 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 losid, el nombre será «Presupuestos 2025 Leer más».- El elemento referenciado puede estar oculto con
hiddenoaria-hidden; su texto se usa igual para el nombre. Eso permite textos solo para el nombre sin mostrarlos. aria-labelyaria-labelledbyno funcionan de forma fiable en elementos sin rol o con roles genéricos (div,span) ni en algunos roles de texto, comoparagraph(el dep),codeostrong, que prohíben expresamente el nombre. Poneraria-labelen 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…). Untextbox,comboboxoslidernecesitaaria-label,aria-labelledbyo 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-labelyaria-labelledbysolo 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.