La Accesibilidad (a11y) como Estándar de Ingeniería

Existe una idea errónea y persistente en el desarrollo Frontend: creer que nuestro trabajo termina cuando la interfaz se ve igual al diseño de Figma. Si alguna vez has pensado que la accesibilidad es algo que se añade «si queda tiempo» al final del sprint, este artículo es para ti.

Como ingenieros Senior, debemos entender que una aplicación que no es accesible es, por definición, una aplicación con deuda técnica.

La accesibilidad (a11y) no se trata solo de ayudar a personas con discapacidad visual; se trata de construir sistemas robustos, inclusivos y universalmente utilizables. En el Día 12 hablábamos de que el Frontend no es «pintar cajitas», es gestionar un entorno hostil. La accesibilidad es la disciplina que asegura que esas «cajitas» funcionen para el 100% de los usuarios, independientemente de cómo interactúen con la máquina.


¿Por qué la accesibilidad es un problema de ingeniería?

Si necesitas argumentos más allá de la empatía para convencer a tu equipo o a tu Product Owner, aquí tienes los argumentos técnicos:

  1. Calidad de Código y SEO: Una web accesible utiliza HTML semántico. Esto no solo ayuda a los lectores de pantalla, sino que crea un DOM más limpio, más fácil de mantener y que los motores de búsqueda (como Google) entienden mucho mejor.
  2. Testabilidad: Las herramientas de testing automatizado (E2E) a menudo dependen de selectores semánticos o roles ARIA. Un sitio accesible es mucho más fácil de testear automáticamente que una «sopa de divs».
  3. El Efecto «Curb-Cut» (Rampa de acera): Las características diseñadas para la accesibilidad terminan beneficiando a todos. La navegación por teclado ayuda a los «power users»; los subtítulos ayudan a quienes están en entornos ruidosos; un buen contraste ayuda cuando usas el celular bajo el sol.

Los 4 Pilares de la Accesibilidad

Para empezar, debemos enfocarnos en:

  1. Semántica: Usar los elementos correctos para el propósito correcto (un botón es un botón, no un div clickable).
  2. Navegación por Teclado: Todo lo que se puede hacer con el mouse debe poder hacerse con la tecla Tab, Enter y Espacio.
  3. Contraste y Color: No usar el color como único medio para transmitir información (ej. errores de formulario) y asegurar un contraste suficiente entre texto y fondo.
  4. Estados y ARIA: Informar a las tecnologías de asistencia cuando algo cambia en la pantalla (un modal que se abre, una lista que se actualiza).

🛠️ Accesibilidad en la Práctica: Angular

Angular es poderoso, pero si no tienes cuidado, puedes crear componentes inaccesibles muy fácilmente.

1. El síndrome del (click) en el lugar equivocado

Es muy común ver desarrolladores que, por pereza de estilizar un botón, usan un div o un span con un evento click.

❌ La mala práctica (Inaccesible):

HTML

<div class="mi-boton-falso" (click)="guardarDatos()">
  Guardar
</div>

✅ La buena práctica (Semántica):

HTML

<button (click)="guardarDatos()">
  Guardar
</button>

<div 
  role="button" 
  tabindex="0" 
  (click)="guardarDatos()"
  (keydown.enter)="guardarDatos()"
  (keydown.space)="guardarDatos()">
  Guardar
</div>

2. Botones de solo íconos

Cuando usas íconos de librerías como Material Icons o FontAwesome sin texto acompañante, el lector de pantalla no sabe qué hace ese botón.

❌ La mala práctica:

HTML

<button mat-icon-button (click)="borrarItem()">
  <mat-icon>delete</mat-icon>
</button>

✅ La buena práctica (aria-label):

HTML

<button mat-icon-button (click)="borrarItem()" aria-label="Eliminar elemento de la lista">
  <mat-icon>delete</mat-icon>
</button>

🛠️ Accesibilidad en la Práctica: Flutter

En Flutter, como no tenemos HTML, dibujamos píxeles en un canvas. Esto hace que el sistema de accesibilidad dependa enteramente del Árbol Semántico (Semantics Tree) que Flutter construye en paralelo al árbol de widgets.

1. Imágenes y elementos decorativos

Si usas una imagen que aporta información, debes describirla. Si es decorativa, debes ocultarla al lector de pantalla para no generar ruido.

❌ La mala práctica:

Dart

// El lector de pantalla dirá "imagen" sin contexto.
Image.asset('assets/logo_empresa.png')

✅ La buena práctica (semanticLabel o excludeSemantics):

Dart

// Si la imagen es importante:
Image.asset(
  'assets/logo_empresa.png',
  semanticLabel: 'Logotipo de Weincode, empresa de desarrollo',
)

// Si la imagen es puramente decorativa (un fondo, una mancha):
ExcludeSemantics(
  child: Image.asset('assets/adorno_fondo.png'),
)

2. Gestos personalizados y el Widget Semantics

Si usas un GestureDetector para crear un botón personalizado, el lector de pantalla no sabrá que es un elemento interactivo a menos que se lo digas.

❌ La mala práctica:

Dart

GestureDetector(
  onTap: () => print('Custom Tap'),
  child: Container(
    padding: EdgeInsets.all(12),
    color: Colors.blue,
    child: Text('Botón Personalizado'),
  ),
)
// TalkBack/VoiceOver leerá el texto, pero no anunciará que es "tocable" o un botón.

✅ La buena práctica (Envolver en Semantics):

Dart

Semantics(
  button: true, // Le dice al lector que esto se comporta como un botón
  label: 'Botón Personalizado', // Opcional si el hijo ya tiene texto claro
  onTap: () => print('Custom Tap'), // Vincula la acción semántica
  child: GestureDetector(
    // ... tu diseño visual
    child: Container(/*...*/)
  ),
)
// Mejor aún: Usa widgets nativos como ElevatedButton o InkWell que ya manejan semantics.

3. Tamaño del objetivo táctil (Tap Targets)

En móviles, la accesibilidad también es motora. Botones muy pequeños son difíciles de pulsar para personas con temblores o dedos grandes. Las guías (Android/iOS) recomiendan un mínimo de 48x48dp o 44x44pt.

✅ La buena práctica en Flutter:

Dart

// Flutter a menudo maneja esto en widgets Material, 
// pero si haces iconos custom, usa IconButton que tiene padding interno.

IconButton(
  icon: Icon(Icons.menu),
  onPressed: () {},
  // Puedes asegurar el tamaño mínimo visualmente o con constraints
  constraints: BoxConstraints(minWidth: 48.0, minHeight: 48.0),
)

Conclusión

La accesibilidad no es un «extra». Es la diferencia entre construir un producto profesional o un prototipo excluyente. Como ingenieros, nuestra responsabilidad es garantizar que la tecnología que creamos sirva a la humanidad en toda su diversidad.

Empieza hoy. No intentes arreglar todo de golpe, pero comprométete a que cada nuevo componente que escribas a partir de ahora sea accesible por defecto

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio