♿ 1.4 · Accesibilidad Web: la web es para todas las personas

⏱ 6h 00min ⚡ 100 XP 🏅 Aprendiz 📖 Fundamentos del Web FullStack
"La accesibilidad no es para 'otros': es para todos. Hoy, mañana, o en 30 años."

🎯 Objetivo del tema

Al terminar este tema serás capaz de: Al terminar este tema serás capaz de explicar qué es la accesibilidad web y por qué no es opcional, identificar las 4 categorías de discapacidad que debes contemplar, aplicar los 4 principios WCAG (Perceptible, Operable, Comprensible, Robusto) a tu código HTML/CSS, y auditar una página con herramientas como Lighthouse y WAVE para detectar barreras.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

🗺️ Mapa del tema

Según la OMS, el 15% de la población mundial vive con alguna forma de discapacidad. Además, todos envejecemos, todos nos lesionamos alguna vez, y todos tenemos momentos donde no podemos usar el mouse (cargando cosas, en una pantalla rota, en el transporte público). La accesibilidad no es caridad: es diseñar productos que funcionen para el 100% de las personas.

1. Qué es accesibilidad y por qué importa

Más allá de la discapacidad: la accesibilidad es usabilidad universal.

2. Las 4 categorías de discapacidad

Visual, auditiva, motora y cognitiva: cada una requiere soluciones distintas.

3. WCAG: los 4 principios (POUR)

Perceptible, Operable, Comprensible, Robusto: el marco legal y ético internacional.

4. Contraste, color y tipografía

Cómo elegir combinaciones que TODOS puedan leer, incluyendo baja visión y daltonismo.

5. Navegación por teclado y focus

El 30% de usuarios no usa mouse: tu página DEBE funcionar solo con teclado.

6. ARIA: cuando HTML no alcanza

Roles, propiedades y estados: cómo enriquecer el HTML para lectores de pantalla.

1.4.1 Qué es accesibilidad y por qué importa

Accesibilidad web significa que personas con discapacidad pueden percibir, entender, navegar e interactuar con tu página, y contribuir a ella. Es lo opuesto a una 'barrera': un elemento que excluye a alguien. No es opcional: en México y muchos países es OBLIGACIÓN LEGAL.

Los tres argumentos a favor

  • Ético: excluir personas por diseño es discriminación. Punto.
  • Legal: en México, la Ley Federal de Telecomunicaciones y la NOM-151 exigen accesibilidad. En la UE y EE.UU. las multas son millonarias.
  • Comercial: el 15% de la población mundial + 100% que envejece + 100% que en algún momento tiene una limitación = un mercado enorme que tus competidores ignoran.
⭐ Mentalidad: No diseñas para 'personas con discapacidad'. Diseñas para el siguiente escenario: tu usuario tiene los ojos cansados, una mano ocupada, o está en un lugar con mucho ruido. La accesibilidad cubre TODOS esos casos.

El mito del '1% de usuarios'

Algunas empresas argumentan 'solo el 1% de nuestros usuarios necesita accesibilidad' para no invertir en ella. El dato real, según la OMS y la W3C:

CondiciónPorcentaje de la población
Discapacidad visual (de leve a ceguera total)Aproximadamente 10%.
Discapacidad auditivaAproximadamente 5%.
Discapacidad motora (incluye temblor, Parkinson)Aproximadamente 8%.
Discapacidad cognitiva (dislexia, TDAH, autismo)Aproximadamente 15%.
Alguna discapacidad permanente o temporal15-20% de la población mundial.
💡 Y los temporales: Suma a eso usuarios temporales: brazo enyesado, ojos irritados por una cirugía, ambiente ruidoso, pantalla rota, conexión lenta. La accesibilidad te hace mejor para TODOS.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

1.4.2 Las 4 categorías de discapacidad

Para diseñar bien, hay que entender las barreras. Las WCAG dividen las discapacidades en 4 categorías. Cada una requiere soluciones diferentes: lo que ayuda a una persona puede no servir a otra.

CategoríaEjemplosBarrera típicaSolución web
VISUALCeguera, baja visión, daltonismo.No poder leer texto, no distinguir colores, no ver imágenes.Texto alt en imágenes, alto contraste, lectores de pantalla.
AUDITIVASordera, hipoacusia.No escuchar audios, no entender videos sin subtítulos.Subtítulos en videos, transcripciones de audio.
MOTORATemblor, parálisis, amputación, Parkinson.No usar mouse, clics imprecisos, no arrastrar.Navegación por teclado, áreas de clic grandes, atajos.
COGNITIVADislexia, TDAH, autismo, baja alfabetización.Dificultad para leer, concentrarse, entender.Lenguaje claro, estructura predecible, sin parpadeos.

Además de estas 4 categorías, considera la accesibilidad TEMPORAL: brazo enyesado, ojos cansados, ambiente ruidoso, conexión lenta. Y la accesibilidad SITUACIONAL: usuario con prisa, en transporte público, con luz solar directa en la pantalla. Las buenas prácticas de WCAG cubren todos estos casos.

⭐ Universal Design: Una página accesible para una persona ciega con lector de pantalla también es accesible para alguien con los ojos irritados por una cirugía. La accesibilidad es ganancia para todos.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

1.4.3 WCAG y los 4 principios POUR

Las Pautas de Accesibilidad para el Contenido Web (WCAG, por sus siglas en inglés) son el estándar internacional creado por la W3C. Organizan TODAS las reglas de accesibilidad alrededor de 4 principios fáciles de recordar, con el acrónimo POUR.

PrincipioPregunta centralEjemplo de falloCómo arreglarlo
PERCEPTIBLE¿El usuario puede PERCIBIR la información?Imagen sin texto alternativo.Agregar alt descriptivo en todas las imágenes.
OPERABLE¿El usuario puede OPERAR la interfaz?Botón que solo funciona con mouse.Hacer que funcione con teclado y agregar area de clic grande.
COMPRENSIBLE¿El contenido es COMPRENSIBLE?Lenguaje técnico sin explicar, errores sin pistas.Escribir en lenguaje claro y mostrar mensajes de error útiles.
ROBUSTO¿Funciona con tecnologías de asistencia?HTML mal formado que rompe el lector de pantalla.Validar HTML, usar roles ARIA cuando haga falta.

Los 3 niveles de conformidad

  • Nivel A: mínimo indispensable. Sin esto, hay contenido INACCESIBLE para grupos enteros (ej: video sin subtítulos excluye a sordos).
  • Nivel AA: el estándar legal en la mayoría de países. Cumple la mayoría de usuarios (ej: contraste mínimo 4.5:1).
  • Nivel AAA: oro puro. A veces imposible de cumplir para TODO el contenido (ej: contraste 7:1 + lenguaje de nivel primaria).
⭐ Apunta a AA: En la práctica, tu objetivo es Nivel AA. Es lo que exige la ley en la mayoría de países y lo que Lighthouse y WAVE verifican por defecto. Nivel AAA es aspiracional para contenido crítico (educación, salud, gobierno).
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

1.4.4 Contraste, color y tipografía accesibles

El contraste de color es la barrera más fácil de detectar y la más común. Según estudios, el 8% de hombres y 0.5% de mujeres tienen algún grado de daltonismo. Una combinación de colores 'bonita' para ti puede ser INVISIBLE para ellos.

La regla 4.5:1

Para texto normal, la proporción de contraste entre el color del texto y el color de fondo debe ser al menos 4.5:1 (Nivel AA). Para texto grande (18pt o 14pt bold), basta 3:1. Esto se mide con fórmulas de luminancia relativa, pero hay herramientas que lo calculan por ti: WebAIM Contrast Checker, Stark, axe DevTools.

CombinaciónContrasteCumple AA
Negro sobre blanco21:1✅ Sí (con holgura).
Gris #767676 sobre blanco4.54:1✅ Sí (apenas).
Gris #999 sobre blanco2.85:1❌ No (texto normal).
Amarillo #FF0 sobre blanco1.07:1❌ No (ilegal para AA).
Azul #0066CC sobre blanco6.37:1✅ Sí.

Nunca comuniques solo con color

⭐ Regla WCAG 1.4.1: Si tu formulario muestra 'campo inválido' solo con un borde rojo, un usuario daltónico no lo va a notar. Combina SIEMPRE color + texto o icono. Ejemplo: borde rojo + mensaje 'Este campo es obligatorio' + icono ⚠.

Tipografía accesible

  • Tamaño mínimo: 16px para texto corrido. Para texto de UI (botones, labels), 14px mínimo.
  • Interlineado: 1.5x el tamaño de la fuente como mínimo.
  • Longitud de línea: entre 50 y 75 caracteres (ch a monoespaciado).
  • Alineación: justificado solo en columnas estrechas. Mejor izquierda para texto largo.
  • Familias sans-serif (Arial, Helvetica, Inter, Roboto) son más legibles en pantalla que las serif.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

1.4.5 Navegación por teclado y focus

El 30% de usuarios con discapacidad motora NO usa mouse. Personas ciegas navegan exclusivamente con teclado. Tu página DEBE ser operable solo con Tab, Enter, flechas, Escape y atajos. Si no lo es, estás excluyendo a millones de personas.

El orden del foco

Cuando el usuario presiona Tab, el foco debe ir al siguiente elemento interactivo en orden LÓGICO de lectura (de izquierda a derecha, arriba a abajo en idiomas occidentales). El orden natural del DOM suele funcionar, pero a veces el CSS lo rompe (position: absolute, flexbox con order personalizado). En ese caso, usa tabindex="0" para forzar el orden.

El indicador de foco DEBE verse

/* Mal: quita el focus visible y no pone nada en su lugar */
button:focus { outline: none; }

/* Bien: focus visible, claro y con buen contraste */
button:focus-visible {
  outline: 3px solid #FF6B00;
  outline-offset: 2px;
}

/* O personalizar para cada estado */
button:focus {
  box-shadow: 0 0 0 3px rgba(255, 107, 0, 0.5);
}

Estilos de focus accesibles (CSS)

El 'skip link'

El skip link (enlace de salto) es un enlace invisible al inicio de la página que permite a usuarios de teclado saltarse el menú de navegación e ir directo al contenido. Aparece solo cuando recibe foco con Tab. Es un detalle pequeño que mejora enormemente la experiencia.

<!-- Al inicio del <body> -->
<a href="#contenido-principal" class="skip-link">
  Saltar al contenido principal
</a>

<!-- ... header y nav ... -->

<main id="contenido-principal" tabindex="-1">
  <!-- El contenido principal -->
</main>

Skip link en HTML

/* Skip link: invisible por defecto, visible al recibir foco */
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: #000;
  color: #fff;
  padding: 8px 16px;
  z-index: 100;
}
.skip-link:focus {
  top: 0;
}

CSS del skip link

⭐ Regla de oro: Nunca uses outline: none sin reemplazarlo por otro indicador de foco visible. Es uno de los errores de accesibilidad más comunes y más dañinos.
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

1.4.6 ARIA: cuando HTML no alcanza

ARIA (Accessible Rich Internet Applications) es un conjunto de atributos especiales que se agregan al HTML para hacerlo más comprensible para las tecnologías de asistencia. La regla #1 de ARIA es: usa HTML semántico primero, y solo agrega ARIA cuando no haya una etiqueta que exprese lo que necesitas.

Los 3 tipos de atributos ARIA

TipoQué haceEjemplo
RolesDefine QUÉ es un elemento.role="navigation", role="dialog", role="alert".
PropiedadesDefine CARACTERÍSTICAS del elemento.aria-label="Cerrar", aria-required="true", aria-describedby="instrucciones".
EstadosDefine ESTADOS DINÁMICOS del elemento.aria-expanded="false", aria-checked="true", aria-disabled="true".

Casos de uso comunes

<!-- Botón solo con icono: necesita texto accesible -->
<button aria-label="Cerrar ventana">
  <svg aria-hidden="true">...</svg>
</button>

<!-- Formulario con descripción adicional -->
<label for="email">Correo electrónico</label>
<input type="email" id="email"
       aria-describedby="ayuda-email"
       aria-required="true">
<small id="ayuda-email">
  Nunca compartiremos tu correo con terceros.
</small>

<!-- Menú desplegable accesible -->
<button aria-expanded="false" aria-controls="menu-1">
  Menú
</button>
<ul id="menu-1" role="menu" hidden>
  <li role="menuitem"><a href="/">Inicio</a></li>
  <li role="menuitem"><a href="/blog">Blog</a></li>
</ul>

Ejemplos de ARIA en uso

⭐ La primera regla de ARIA: Regla de oro de ARIA: 'No uses ARIA si puedes usar HTML semántico'. Si tu <button> necesita aria-label, está bien. Pero si tu <div> con onclick necesita role='button' Y tabindex='0' Y eventos de teclado... mejor usa <button> directamente.

Herramientas para auditar accesibilidad

  • Lighthouse (Chrome DevTools > Lighthouse > Accessibility): auditoría rápida con puntaje 0-100.
  • WAVE (wave.webaim.org): analiza cualquier URL y muestra errores, alertas y mejoras.
  • axe DevTools (extensión de Chrome): auditoría detallada con explicación de cada problema.
  • Léelo en voz alta: macOS VoiceOver (Cmd+F5), Windows Narrator (Ctrl+Win+Enter), NVDA o JAWS (gratuito el primero, pago el segundo).
🎬
Video del instructor

El administrador aún no ha insertado un video para esta sección.

📚 Contenido ampliado

Material adicional, referencias externas verificadas y ejemplos extendidos.

🤖 AI Mission

La auditoría de accesibilidad es trabajo en pareja: tú entiendes el contexto, la IA ve patrones.

Misión: Toma la página 'Sobre mí' que creaste en el Tema 1.3 (o cualquier página HTML que tengas a mano). Pídele a la IA que haga una auditoría de accesibilidad: que revise contraste, navegación por teclado, atributos alt, estructura de encabezados, uso de ARIA. Compara sus hallazgos con los de Lighthouse o WAVE. ¿La IA coincide? ¿Vio algo que la herramienta no vio? ¿La herramienta fue más estricta?

Pasos sugeridos

  1. Abre tu página 'Sobre mí' en Chrome, ve a DevTools > Lighthouse > marca solo 'Accessibility' > 'Analyze page load'.
  2. Anota el puntaje de Lighthouse (0-100) y los 3 principales problemas que reporta.
  3. Pídele a la IA: 'Audita este HTML por accesibilidad WCAG nivel AA. Revisa: contraste de color, atributos alt, jerarquía de encabezados, navegación por teclado, roles ARIA. Dame una lista priorizada de correcciones.' Pega tu código.
  4. Compara las dos listas. ¿Coinciden en los problemas principales? ¿Hay problemas en una lista que no aparecen en la otra?
  5. Aplica las correcciones que TÚ entiendas. Anota en tu cuaderno, bajo 'IA vs Lighthouse': ¿cuál fue más estricta? ¿Cuál te dio mejores justificaciones?

📓 Entregable: Captura del puntaje de Lighthouse antes y después de las correcciones, lista priorizada de la IA, y media página de cuaderno comparando las dos auditorías con tu opinión sobre cuál confiarías más en un proyecto real.

🚫 Errores típicos de razonamiento

Error 1: Quitar el outline del focus con CSS y no reemplazarlo con nada visible.
Por qué: Es uno de los errores más comunes en sitios 'modernos'. El desarrollador ve el outline azul/negro como 'feo' y lo quita con `button:focus { outline: none; }`. Pero el outline era el ÚNICO indicador visual de qué elemento tiene el foco. Sin él, un usuario de teclado no sabe dónde está, no puede navegar, y se pierde. Tu página se vuelve INUTILIZABLE con teclado.
Error 2: Comunicar información solo con color (ej: 'campo inválido' solo con borde rojo).
Por qué: El 8% de los hombres y 0.5% de las mujeres no distingue ciertos colores. Si tu único indicador de error es el color rojo, ellos no lo ven. Además, un usuario con pantalla en blanco y negro (modo alto contraste) tampoco. WCAG 1.4.1 prohíbe explícitamente esto. Solución: combina color + texto + icono, SIEMPRE.
Error 3: Usar <div> con onclick en vez de <button>.
Por qué: Un <div> con onclick NO es accesible: no recibe foco con Tab, no responde a Enter, los lectores de pantalla no lo anuncian como botón. La tentación es grande porque <button> tiene estilos por defecto 'feos'. Pero puedes estilizar <button> como quieras con CSS. Si necesitas un <div>, entonces agrega role='button' + tabindex='0' + eventos de teclado. Pero casi siempre, es mejor usar <button>.
Error 4: Olvidar subtítulos en videos y transcripciones en audios.
Por qué: Para una persona sorda, un video sin subtítulos es INVISIBLE. Pierde el 100% del contenido. Lo mismo con un audio sin transcripción. Es además una de las verificaciones automáticas de WCAG nivel A: 'si tiene audio, debe tener alternativa textual'. Solución: agrega <track> con kind='subtitles' en <video>, o un enlace a la transcripción escrita.
Error 5: Usar ARIA para 'arreglar' HTML mal escrito.
Por qué: La primera regla de ARIA oficial dice: 'No uses ARIA si puedes usar HTML semántico'. Muchas veces el desarrollador escribe <div role='button' tabindex='0'> porque 'es más fácil' que <button>, sin saber que <button> trae gratis: foco por teclado, evento Enter, anuncio de 'botón' por lectores de pantalla, estilo de foco nativo. Usar ARIA sobre HTML roto es como pintar una pared con humedad: se ve bien 5 minutos, después todo se cae.

🧪 Laboratorio práctico

Auditar es el primer paso. Corregir, el segundo. Validar, el tercero.

Laboratorio: Auditoría y corrección de accesibilidad de tu página 'Sobre mí'

Objetivo: Tomar la página 'Sobre mí' del Tema 1.3, auditarla con al menos 2 herramientas (Lighthouse + WAVE), corregir los problemas encontrados, y verificar que el puntaje de accesibilidad suba a 95+ en Lighthouse.

Pasos

  1. Abre tu página 'Sobre mí' del Tema 1.3 en Chrome.
  2. Ejecuta Lighthouse: DevTools > Lighthouse > Accessibility > Analyze page load. Anota el puntaje inicial.
  3. Ejecuta WAVE en https://wave.webaim.org/ pegando la ruta local de tu página. Anota los errores y alertas.
  4. Haz una lista priorizada de los problemas (errores primero, alertas después).
  5. Corrige uno por uno: imágenes sin alt, jerarquía de encabezados, contraste de color, focus visible, idioma del documento.
  6. Si usas iconos sin texto visible, agrega aria-label a los botones.
  7. Si tienes un menú desplegable personalizado (con <div>), conviértelo a <button> + <ul> con atributos aria-expanded y aria-controls.
  8. Agrega un 'skip link' al inicio del <body> para saltar al contenido principal.
  9. Vuelve a correr Lighthouse. Verifica que el puntaje sea 95+.
  10. Prueba la página con el lector de pantalla de tu sistema (Narrator en Windows, VoiceOver en macOS). Verifica que la navegación por Tab sea coherente.
  11. Haz commit: 'feat: accesibilidad nivel AA verificada en página Sobre mí'.

📓 Entregable: Capturas de: (1) puntaje inicial de Lighthouse, (2) reporte de WAVE con los errores, (3) puntaje final después de las correcciones, (4) uso de lector de pantalla navegando la página, (5) commit final en Git.

📓 Tu cuaderno: Anota pseudocódigo, diagramas, errores que encontraste y respuestas a "explica sin código". La escritura manual refuerza tu razonamiento. Tu profesor puede pedirte que subas fotos de páginas específicas.