Accesibilidad Visual con CSS
Cómo garantizar que tu sitio sea legible y usable para todas las personas, sin importar sus capacidades visuales.
1. ¿Por qué es importante la accesibilidad visual?
La accesibilidad visual se centra en que el contenido sea percibible para usuarios con deficiencias de visión, daltonismo, baja visión o sensibilidad a los movimientos. Cumplir con WCAG 2.2 no solo evita sanciones legales, sino que también mejora la experiencia de todos los visitantes.
2. Principios clave de CSS para la accesibilidad visual
Problema común
- Contraste insuficiente entre texto y fondo.
- Fuentes pequeñas o sin ajuste de tamaño.
- Enlaces sin foco visible.
- Animaciones que pueden causar mareos.
- Colores que no consideran el daltonismo.
Solución con CSS
- Usar
color-contrast()o herramientas como axe para asegurar un contraste ≥ 4.5:1. - Definir tamaños relativos (
rem,em) y permitirtext‑size‑adjust. - Aplicar
:focus-visiblecon contornos claros. - Respetar
prefers-reduced-motiony reducir animaciones. - Implementar paletas compatibles con daltonismo usando
color-schemeyhsl().
3. Técnicas CSS esenciales
3.1 Contraste de color
Utiliza variables CSS y la función color-contrast() (disponible en navegadores modernos) para garantizar el contraste adecuado.
:root {
--color-bg: #ffffff;
--color-fg: #1a1a1a;
}
body {
background-color: var(--color-bg);
color: var(--color-fg);
}
/* Ajuste automático si el contraste no cumple */
@media (prefers-contrast: high) {
:root {
--color-bg: #000000;
--color-fg: #ffffff;
}
}
3.2 Tipografía y escalado
Define tamaños en rem y habilita el escalado del texto.
html {
font-size: 100%; /* 16px base */
}
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
font-size: 1rem; /* 16px */
}
h1, h2, h3 {
line-height: 1.2;
margin-top: 1.5rem;
}
/* Permitir que los usuarios aumenten el tamaño */
@media (prefers-reduced-motion: reduce) {
html {
text-size-adjust: 120%;
}
}
3.3 Enfoque visible
Los navegadores ofrecen :focus-visible para mostrar contornos solo cuando el foco es mediante teclado.
a:focus-visible,
button:focus-visible {
outline: 3px solid #ff9800;
outline-offset: 2px;
}
3.4 Reducción de movimiento
Respeta la preferencia del usuario para disminuir animaciones.
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.001ms !important;
transition-duration: 0.001ms !important;
scroll-behavior: auto !important;
}
}
3.5 Temas claros/oscurecidos (prefers‑color‑scheme)
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #121212;
--color-fg: #e0e0e0;
}
}
body {
background: var(--color-bg);
color: var(--color-fg);
}
4. Comparativa de técnicas: Solución manual vs. Variables CSS + Media Queries
Enfoque manual (ejemplo tradicional)
.btn-primary {
background: #0066cc;
color: #fff;
}
.btn-primary:hover {
background: #005bb5;
}
Problema: Si el contraste no es suficiente, cada botón debe ser revisado por separado.
Enfoque con variables y prefers-contrast
:root {
--primary-bg: #0066cc;
--primary-fg: #fff;
}
.btn-primary {
background: var(--primary-bg);
color: var(--primary-fg);
}
@media (prefers-contrast: high) {
:root {
--primary-bg: #004999; /* mayor contraste */
}
}
Ventaja: Un único punto de ajuste mejora la mantenibilidad y garantiza cumplimiento automático.
5. Buenas prácticas y checklist rápido
- ✅ Usa
rem/empara tamaños, nuncapxfijo. - ✅ Verifica contraste con herramientas como WAVE o Chrome DevTools Accessibility.
- ✅ Implementa
:focus-visibley evitaoutline: nonesin sustituto. - ✅ Respeta
prefers-reduced-motionyprefers-color-scheme. - ✅ Prueba con simuladores de daltonismo (e.g., Colorblindly).
- ✅ Añade
aria-labelyrolecuando sea necesario, pero sin sobrecargar el CSS.
6. Resolución de problemas (troubleshooting)
6.1 El contraste sigue siendo bajo en modo oscuro
Comprueba que las variables usadas en prefers-color-scheme: dark tengan valores con suficiente diferencia de luminancia. Usa la función color-contrast() para generar dinámicamente colores adecuados.
@media (prefers-color-scheme: dark) {
:root {
--color-bg: #121212;
--color-fg: color-contrast(#121212, #ffffff, #b0b0b0);
}
}
6.2 Los enlaces no muestran foco en Safari
Safari todavía necesita un prefijo -webkit-focus-ring-color para algunos casos.
a:focus-visible {
outline: 2px solid -webkit-focus-ring-color;
outline-offset: 2px;
}
7. Rendimiento y escalabilidad
Utilizar variables CSS y @media permite que el navegador calcule los estilos en tiempo de ejecución sin recargar CSS adicional. Evita duplicar reglas y mantén los archivos por debajo de 100 KB para una carga rápida, especialmente en dispositivos móviles con conexiones lentas.
Accesibilidad Visual con CSS: Guía Completa y Ejemplos Prácticos