Saltar al contenido principal
Ramon Carrillo
Todos los posts
10 min de lecturaChecklist

La checklist WCAG 2.1 AA que aplico en cada proyecto

Una checklist práctica y ordenada para enviar proyectos accesibles con Next.js + Tailwind — landmarks, skip links, soporte de teclado, contraste, reflujo y formularios — destilada tras auditar cuatro sitios en una mañana.

Por qué tengo una checklist

Cada proyecto en mi portafolio pasa por la misma revisión de accesibilidad antes de que lo dé por terminado. No porque un cliente lo haya pedido — porque he visto demasiados portafolios "pulidos" caerse a pedazos en cuanto los recorres con teclado, o los abres en un celular con zoom al 200%. Un portafolio de desarrollador que no pasa WCAG 2.1 AA es una señal clara: o el autor no conoce las reglas, o las conoce y las saltó.

Este post es la checklist real que apliqué a cuatro proyectos en vivo en una sentada — el Google Maps RAG Assistant, este portafolio, un sitio de marketing de chimeneas y techos, y un demo de e-commerce. Todo lo que está aquí es algo por lo que yo mismo he enviado un PR. Sin teoría, sin viñetas de "mundo ideal" que yo mismo no aplique.

WCAG es un estándar grande, así que no voy a pretender que esto cubre todo. La meta es conformidad AA en un proyecto típico de Next.js + Tailwind + shadcn/ui. Si estás haciendo trabajo de gobierno o necesitas Section 508, profundiza más. Para un portafolio, esta checklist es lo que separa "lo suficientemente accesible para que un usuario de lector de pantalla realmente pueda usarlo" de "le agregué una etiqueta alt una vez."

Estructura: seis bloques, más o menos en orden

Trabajo la lista de arriba hacia abajo porque arreglos tempranos suelen prevenir los siguientes. Si tus landmarks de HTML están mal, el skip link que estás a punto de agregar va a saltar al lugar equivocado.

1. Landmarks y estructura del documento

La primera acción de un usuario de lector de pantalla suele ser "saltar al contenido principal" o "listar los landmarks." Si tu página tiene cinco <div>s en una gabardina, se quedan atorados.

2. Skip link

Uno de los arreglos con mayor relación valor-por-línea-de-código. Un skip link permite a usuarios de teclado saltarse tu navegación en cada página — sin él, recorren los mismos ocho ítems del menú en cada ruta.

// app/layout.tsx
<body>
  <a
    href="#main"
    className="sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-50 focus:rounded-md focus:bg-primary focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-primary-foreground"
  >
    Saltar al contenido principal
  </a>
  {children}
</body>

El patrón sr-onlyfocus:not-sr-only lo mantiene oculto hasta el primer Tab, y entonces aparece. Cubre WCAG 2.4.1 Bypass Blocks.

3. Soporte de teclado

La regla que tengo en la cabeza: si puedo hacerlo con el mouse, debo poder hacerlo solo con el teclado, y debo poder ver dónde estoy en todo momento.

4. Color y contraste

Aquí es donde veo más fallos silenciosos. Un diseño se ve bien en el monitor calibrado del diseñador y es ilegible en una laptop barata en una cafetería.

Aquí uso herramientas reales — @axe-core/cli, Lighthouse de Chrome o el excelente sitio Accessible Colors — no checks a ojo.

5. Touch targets y reflujo

La accesibilidad móvil no es una categoría aparte. Es WCAG.

6. Formularios y contenido en vivo

Los formularios son donde la UX para lectores de pantalla brilla o se desploma.

Las cosas que no están en la lista (y por qué)

No reviso cada criterio de WCAG AA en cada pasada. Algunos los dejo al framework, otros los confío a las herramientas.

La capa de automatización

Una checklist solo es útil si se corre. Combino la revisión manual con tres herramientas:

  1. @axe-core/cli en CI para los fallos obvios (alt faltantes, labels faltantes, IDs duplicados, contraste malo en elementos estáticos).
  2. Lighthouse sobre la URL de preview desplegada para un puntaje general aproximado — el número no es la meta, pero una caída de 100 a 92 es señal de revisar.
  3. Pasada manual de teclado, cada vez, en cada ruta. Recorre toda la página con Tab. Activa cada botón y cada link. Abre cada modal. Cierra cada modal. Esto atrapa todo lo que las herramientas automatizadas no pueden — bugs de orden de tab, anillos de focus faltantes, saltos inesperados de focus.

No creo en confiar solo en las herramientas de accesibilidad. Axe atrapa quizá el 40% de los problemas reales; el otro 60% necesita una persona que entienda qué intenta hacer la página. Pero ese 40% automatizado sale gratis una vez configurado, y atrapa regresiones que de otra forma yo enviaría.

Cómo aplico esto a un proyecto existente

Cuando audito un sitio que ya está en vivo (el caso común — Chimneys Plus, EcoShop, Lumina en mi portafolio), lo hago en un orden específico:

  1. Lee el DOM primero. Abre la página desplegada, click derecho → Inspeccionar, y simplemente lee la estructura HTML. Antes de correr cualquier herramienta quiero ver: ¿hay un <main>? ¿Un solo <h1>? ¿Landmarks con sentido? Si los huesos están mal, arreglar el contraste es maquillar un cadáver.
  2. Recorre la página con Tab. Sin herramientas, sin lector de pantalla, solo Tab. Estoy buscando: ¿aparece el anillo de focus? ¿se mantiene visible? ¿el orden de tab coincide con el orden visual? ¿a dónde va el focus cuando abro un modal — y a dónde regresa cuando lo cierro?
  3. Corre axe para los fallos estáticos — alts faltantes, labels faltantes, IDs duplicados.
  4. Corre Lighthouse para el puntaje y la auditoría de contraste.
  5. Hazle zoom al 200% y reduce a 320px. ¿Algún scrollbar horizontal? ¿Algún texto recortado?
  6. Arregla en el mismo orden de esta checklist. Landmarks → skip link → teclado → contraste → touch → formularios.

Un layout.tsx mínimo que cubre la mayoría de las bases

Si empezara un proyecto de Next.js desde cero hoy, el layout raíz ya traería la mayor parte de esto incluido:

// app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="es">
      <body className="min-h-screen antialiased">
        <a
          href="#main"
          className="sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-50 focus:rounded-md focus:bg-primary focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-primary-foreground"
        >
          Saltar al contenido principal
        </a>
        <Nav />
        <main id="main">{children}</main>
        <Footer />
      </body>
    </html>
  );
}

Más esto en globals.css:

@layer base {
  *:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
    border-radius: 4px;
  }
}

Ese único archivo y ese bloque de CSS te saca de los tres fallos de WCAG más comunes en apps de Next.js enviadas a producción: lang faltante, skip link faltante y anillos de focus invisibles. Empieza cada proyecto así y ya hiciste más por la accesibilidad que la mayoría de los portafolios en internet.

La verdadera lección

La accesibilidad no es una pasada aparte. Es parte de construir la cosa. La razón por la que puedo correr esta checklist en cuatro proyectos en una mañana es que la mayoría de las casillas ya estaban marcadas mientras escribía el código la primera vez — solo las verifico de nuevo antes de dar algo por terminado.

Si nunca has hecho esta pasada en alguno de tus propios proyectos: empieza por los tres arreglos más baratos y de mayor valor, en este orden.

  1. Agrega lang="es" (o el idioma que sea) a <html> si no lo tiene.
  2. Agrega un skip link.
  3. Reemplaza cualquier anillo de focus tenue con uno sólido de 2px.

Esos tres cambios toman diez minutos y te mueven de "falla los checks básicos" a "pasa la prueba de humo." Todo lo demás en esta lista se construye desde ahí.