TL;DR (Too Long; Didn’t Read... o básicamente: mucho texto, dame el resumen rápido)
Si construyes un campo de formulario personalizado (ej: usando un div con role="textbox" o role="combobox"), debes proveer obligatoriamente un nombre mediante aria-label o aria-labelledby. De lo contrario, el lector de pantalla dirá "Campo de texto", pero no revelará qué se espera que la persona usuaria escriba en él.
El abismo de los inputs mudos
En el afán de evadir el estilo predeterminado del navegador, es usual reinventar componentes de formulario. Sin embargo, al renunciar a las etiquetas nativas <input> vinculadas con un <label>, el desarrollador asume la total responsabilidad de informar al Árbol de Accesibilidad (AOM) sobre la identidad del campo, conforme al Criterio WCAG 4.1.2.
El patrón erróneo: Código Accesible Deficiente
El componente se enuncia como interactivo, pero es incapaz de instruir a la persona usuaria sobre el dato requerido.
<!-- MAL: Rol presente, pero falta el nombre accesible -->
<div class="custom-field" role="textbox" contenteditable="true">
<!-- ¿Nombre? ¿Correo? ¿Contraseña? -->
</div>
La Solución Accesible: Código Recomendado
Se debe proveer una etiqueta clara para compensar la ausencia del HTML nativo.
<!-- BIEN: Nombre descriptivo explícitamente inyectado vía ARIA -->
<div class="custom-field"
role="textbox"
contenteditable="true"
aria-label="Fecha de nacimiento (DD/MM/AAAA)">
</div>Metodología de Verificación y Testing
Pruebas Manuales con Lectores de Pantalla
Con NVDA activo, presionar F para saltar entre campos de formulario. Verificar que el lector de pantalla anuncie correctamente el nombre, tipo y estado del campo. Si el campo no posee una etiqueta vinculada programáticamente, el lector solo anunciará el tipo de control sin contexto. En VoiceOver (iOS), tocar el campo y confirmar que la descripción sea completa.
Inspección del Árbol de Accesibilidad
En Chrome DevTools, seleccionar el elemento afectado en el panel Elements, luego abrir la pestaña Accessibility. Verificar que las propiedades Role, Name y State reflejen correctamente la intención del componente según el criterio WCAG 4.1.2.
Herramientas Automatizadas
Ejecutar Axe DevTools: las reglas aria-* y *-name detectan violaciones del Criterio 4.1.2 (Nombre, Función, Valor). WAVE marca controles sin nombre accesible. Limitación: La sincronización de estados dinámicos (JS) no siempre es verificable de forma automatizada.