DevPath · Aprende a programar ESPTEN

React profesional: TypeScript, SSR y accesibilidad

Accesibilidad (a11y) en React

Accesibilidad: para todos, no opcional

La accesibilidad (abreviada a11y: "a", 11 letras, "y") es construir interfaces que cualquier persona pueda usar, incluidas las que navegan con lector de pantalla, solo con teclado, o con baja visión. No es un extra: es calidad de software (y, a menudo, un requisito legal).

La buena noticia: el 90 % de la accesibilidad es HTML bien hecho.

1) HTML semántico

Usa el elemento correcto para cada cosa. Un <button> ya es enfocable, pulsable con Enter/Espacio y anunciado como botón; un <div onClick> no es nada de eso.

// ❌ Mal: un div no es accesible por teclado ni se anuncia como botón
<div onClick={cerrar}>Cerrar</div>

// ✅ Bien
<button onClick={cerrar}>Cerrar</button>

Lo mismo con <nav>, <main>, <header>, <ul>/<li>, encabezados <h1>…<h6> en orden: dan estructura que las tecnologías de asistencia entienden.

2) Etiquetas asociadas a sus campos

Todo control de formulario necesita una etiqueta asociada. La forma robusta es <label htmlFor={id}> apuntando al id del campo. En JSX se escribe htmlFor (no for, que es palabra reservada en JS), pero en el DOM real se convierte en el atributo for.

<label htmlFor="email">Correo</label>
<input id="email" type="email" />

Al asociarlos: el lector de pantalla anuncia la etiqueta al enfocar el campo, y pulsar la etiqueta enfoca el input (mejor usabilidad para todos).

3) ARIA, solo cuando hace falta

Los atributos ARIA (aria-*) añaden información semántica que el HTML por sí solo no expresa. La primera regla de ARIA es: no uses ARIA si un elemento nativo ya hace el trabajo. Pero es muy útil para matices:

<input aria-required="true" aria-invalid={hayError} />
<button aria-label="Cerrar diálogo">✕</button>     {/* botón con solo un icono */}
<nav aria-label="Principal">…</nav>

4) Foco y navegación por teclado

Mucha gente navega sin ratón. Asegúrate de que:

5) IDs únicos con useId

Asociar label e input por id tiene un problema en React: si el componente se usa varias veces en la página, un id fijo ("email") se duplicaría, y los ids deben ser únicos. La solución es el hook useId, que genera un identificador único y estable (además funciona bien con SSR/hidratación):

function Campo({ etiqueta }) {
  const id = React.useId();
  return (
    <p>
      <label htmlFor={id}>{etiqueta}</label>
      <input id={id} />
    </p>
  );
}

Importante: useId es para ids de accesibilidad (enlazar elementos), no para keys de listas. Reutiliza el mismo id (con sufijos si necesitas varios: ${id}-error) para relacionar elementos del mismo componente.

En los ejercicios de este runtime, usa React.useId() (con el prefijo React.) para generar el id.

Pon esto en práctica

DevPath es un curso práctico: aquí lees la teoría; en la app la pones en práctica con ejercicios que se ejecutan de verdad, sin conexión.

Empezar gratis en la app →
← Renderizado en servidor: CSR, SSR, SSG y Server ComponentsVer el módulo →