Conceptos

HTML semántico

Usar elementos HTML por su significado, no solo por su apariencia predeterminada. Un `<button>` se anuncia como botón; un `<div onclick>` no anuncia nada. La inmensa mayoría de los fallos de accesibilidad tienen su origen en el abandono de la semántica.

El HTML semántico es aquel en el que cada elemento se elige por su significado, no solo por su apariencia. Un <button> es para acciones. Un <nav> envuelve la navegación. Una <table> contiene datos tabulares. Usar un <div> con estilos que imiten un botón para una acción es un fallo semántico — aunque el resultado visual sea idéntico.

La inmensa mayoría de los errores de accesibilidad tienen su origen en el abandono de la semántica. Casi todos los fallos con tecnología de apoyo comparten la misma causa raíz: un elemento genérico haciendo el trabajo para el que fue diseñado un elemento semántico.

Por qué les importa a los lectores de pantalla

Los lectores de pantalla exponen el HTML al usuario a través del árbol de accesibilidad — una representación interna construida a partir del DOM que asigna a cada elemento un rol, un nombre, un estado y propiedades. El árbol de accesibilidad es lo que el usuario escucha realmente.

Un <button> nativo entra en el árbol de accesibilidad como button "Enviar". Un <div> con estilos de botón entra como generic — lo que significa que el lector de pantalla no anuncia nada útil y el usuario no tiene forma de saber que el elemento es interactivo.

La misma lógica se aplica a:

  • Encabezados (<h1><h6>) — los lectores de pantalla permiten a los usuarios saltar entre encabezados para recorrer una página. <div class="heading"> no aparece en la lista de encabezados.
  • Listas (<ul>, <ol>, <li>) — los lectores de pantalla anuncian «lista, 5 elementos» antes de leer. Los <div> que simulan elementos de lista no lo hacen.
  • Formularios — un <input> con una <label> conectada lee «Correo electrónico, campo de texto». Un campo personalizado hecho de divs y contenteditable no lee nada.
  • Tablas — <table> con encabezados <th> de filas y columnas permite a los usuarios navegar por las celdas de datos con el contexto de los encabezados anunciado. Las cuadrículas CSS de divs no lo hacen.

El patrón de sustitución

La solución tiene casi siempre la misma forma:

  • <div onclick="..."><button> (o <a href> para la navegación).
  • <span class="link"><a href>.
  • <div role="heading"> → de <h1> a <h6>.
  • Desplegables personalizados → <select> cuando el diseño lo permite, o un combobox ARIA testado contra patrones establecidos cuando no.
  • Pestañas construidas con <div> estilizados → patrón de pestañas de la Guía de Prácticas de Autoría de ARIA.

Cuándo recurrir a ARIA

La primera regla de ARIA es: no usar ARIA si un elemento nativo cumple la función. Los roles, estados y propiedades de ARIA son un parche para los casos en que el HTML nativo no puede describir el componente que se está construiendo (vistas en árbol, comboboxes de selección múltiple, ciertos patrones de modal). No son un sustituto del uso de <button>.

Una auditoría pragmática

La forma más rápida de detectar la degradación semántica en una base de código: buscar onclick en div y span. Cada coincidencia es un posible fallo. La siguiente más rápida: buscar atributos role=. ARIA está bien en contextos limitados, pero un uso intensivo de ARIA suele indicar que se omitieron elementos nativos por razones de estilo que en realidad no lo requerían.