Accesibilidad en Go: haciendo que el software sea accesible para todos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cuando el código dice: «Te escucho»

\n\n

Imagina que pierdes la vista por un día. Tu aplicación de mensajería favorita en Go de repente se queda en silencio. Los botones no se verbalizan, los formularios no se completan y los errores de validación son solo rectángulos rojos. Desagradable, ¿verdad? Y para millones de personas con discapacidad, esto no es un experimento, sino la realidad.

\n\n

La accesibilidad (o a11y — de «a» + 11 letras + «y») no se trata de «marcar una casilla por cumplir». Se trata de que tu servicio Go no apague la luz para el 15% de la población mundial. En este artículo, analizaremos cómo implementar la accesibilidad en proyectos Go sin fanatismo, pero con un beneficio real. ¡Allá vamos!

\n\n

Por qué la accesibilidad en Go no es una opción, sino un estándar

\n\n

Go es un lenguaje para backend, pero eso no significa que no participe en la creación de una interfaz accesible. Si escribes una API para el frontend, generas HTML en el servidor o creas utilidades CLI, ya estás influyendo en la accesibilidad. La mala noticia: muchos desarrolladores Go piensan que «a11y es cosa de frontend». La buena noticia: puedes solucionarlo en una tarde.

\n\n

¿Qué es la accesibilidad web desde el punto de vista de Go?

\n\n

La accesibilidad web (web accessibility) es la capacidad de un sitio o aplicación para ser utilizado por personas con diferentes limitaciones: visión, audición, motricidad, capacidades cognitivas. En el contexto de Go, esto significa:

\n\n
    \n
  • Un marcado HTML correcto generado por el servidor (por ejemplo, a través de html/template);
  • \n
  • Atributos ARIA correctos para contenido dinámico;
  • \n
  • Navegación lógica con el teclado;
  • \n
  • Mensajes de error claros (no «Error 500», sino «No se pudo guardar el archivo: espacio insuficiente»).
  • \n
\n\n

Y sí, Go es el lenguaje ideal para esto. Su tipificación estricta y herramientas integradas permiten verificar las plantillas sobre la marcha. Pero vayamos por partes.

\n\n

Marcado semántico: el fundamento de la accesibilidad en Go

\n\n

Cuando generas HTML a través de html/template, eres el arquitecto de la interfaz. Si tu código escupe un <div> para cada botón, los lectores de pantalla (screen readers) no entenderán qué elemento es. Pero si usas <button>, dirán: «Botón. Pulse para enviar el formulario».

\n\n

Ejemplo: un formulario accesible en Go

\n\n

Supongamos que escribes un formulario de registro. Opción mala:

\n\n
// Mal: sin semántica\ntmpl := `<div class="form">\n    <div>Nombre</div>\n    <input type="text" id="name">\n    <div class="error">{{.NameError}}</div>\n</div>`\n
\n\n

Opción buena — con <label> y aria-describedby:

\n\n
// Bien: marcado semántico + ARIA\ntmpl := `<form>\n    <label for="name">Nombre</label>\n    <input type="text" id="name" aria-describedby="name-error">\n    <span id="name-error" role="alert">{{if .NameError}}{{.NameError}}{{end}}</span>\n</form>`\n
\n\n

¿Qué cambió? El lector de pantalla ahora sabe: esto es un formulario, el campo de entrada está vinculado a una etiqueta y el error es una alerta. El usuario escuchará: «Nombre. Editar texto. Error: campo obligatorio».

\n\n

Atributos ARIA: cuando el HTML no es suficiente

\n\n

A veces las etiquetas estándar no son suficientes. Por ejemplo, haces pestañas (tabs) con Go + HTMX. Sin ARIA, sonarán como «enlace, enlace, enlace...». Pero con ARIA, sonarán como «Pestaña 1, seleccionada. Pestaña 2. Pestaña 3».

\n\n

Cómo agregar ARIA en plantillas Go

\n\n

Los atributos ARIA se pasan como atributos normales en HTML. Aquí hay un ejemplo para pestañas:

\n\n
<div role="tablist" aria-label="Configuración del perfil">\n    <button role="tab" aria-selected="{{if eq .Tab "profile"}}true{{else}}false{{end}}" \n            aria-controls="panel-profile" id="tab-profile">Perfil</button>\n    <button role="tab" aria-selected="{{if eq .Tab "security"}}true{{else}}false{{end}}" \n            aria-controls="panel-security" id="tab-security">Seguridad</button>\n</div>                

Blogs

Book Recommendations