wandres.dev
ACCESIBILIDAD · prefers-reduced-motion en serio

Transparencia, colores forzados y destellos

prefers-reduced-transparency y su soporte real, qué le hace a tus animaciones el modo de colores forzados, el umbral de destellos que protege contra las crisis fotosensibles, y la auditoría de movimiento completa.

⏱ 18 min

El movimiento no es la única preferencia visual que un sistema operativo expone, y las otras tocan de lleno lo que estás animando: la transparencia, el contraste y los colores forzados cambian el aspecto de tus transiciones o las anulan por completo. Y hay un riesgo distinto del vestibular, más grave y con un umbral numérico definido: los destellos. Esta lección cierra el nivel con esas tres preferencias, el umbral fotosensible y una auditoría que puedes ejecutar en una tarde.

🎯 Al terminar esta lección sabrás
  • Usar prefers-reduced-transparency conociendo su estado real de soporte.
  • Adaptar animaciones al modo de colores forzados y a prefers-contrast.
  • Aplicar el umbral de tres destellos por segundo y saber qué cuenta como destello.
  • Ejecutar una auditoría de movimiento completa sobre un producto existente.

Transparencia reducida

Los sistemas operativos llevan años ofreciendo un ajuste para reducir los efectos de translucidez: fondos esmerilados, barras semitransparentes, capas con desenfoque. Se activa por las mismas razones que el de movimiento y algunas más: la translucidez reduce el contraste efectivo del texto que hay encima, y para alguien con baja visión eso es la diferencia entre leer y no leer.

.panel {
  background: color-mix(in oklab, canvas 70%, transparent);
  backdrop-filter: blur(16px) saturate(1.4);
  transition: backdrop-filter var(--mov-media) linear, background var(--mov-media) linear;
}

@media (prefers-reduced-transparency: reduce) {
  .panel {
    background: canvas;
    backdrop-filter: none;
  }
}

Y el estado del soporte, que hay que decir claro: no es Baseline. Chromium la implementó en 2023 y el resto de motores han ido llegando después; en el momento de escribir esto no puedes darla por disponible en los cuatro. Trátala como mejora progresiva: la versión sin translucidez tiene que ser un caso perfectamente válido de tu diseño, no un apaño, porque a la gente cuyo navegador no soporta la consulta le vas a servir la versión translúcida igualmente.

Hay un beneficio secundario que casi compensa por sí solo el trabajo. backdrop-filter es de las propiedades más caras que existen: obliga al compositor a leer lo que hay detrás del elemento, aplicarle un filtro y volver a componer, en cada fotograma en que algo cambie. Animar un elemento con backdrop-filter encima de contenido que también se mueve es una de las formas más eficaces de tirar los fotogramas a treinta. La rama de transparencia reducida es, además de accesible, notablemente más rápida.

Colores forzados y contraste

El modo de colores forzados —lo que en Windows se llama contraste alto— es más agresivo de lo que la gente cree: el navegador sustituye los colores del autor por una paleta limitada del sistema, ignora los fondos de imagen y elimina las sombras. Todo lo que dependa de color en tu animación deja de funcionar.

@media (forced-colors: active) {
  /* Las sombras no existen aqui: si tu foco dependia de una, no hay foco. */
  .boton:focus-visible {
    outline: 2px solid CanvasText;
    outline-offset: 2px;
  }

  /* Un indicador que se distinguia solo por color necesita otra senal. */
  .pastilla[data-activa] {
    border: 2px solid Highlight;
  }
}

Las tres consecuencias prácticas para animación:

Una transición de color puede no producir ningún cambio visible. Si tu botón “responde” pasando de un gris a otro, en colores forzados los dos son el mismo color del sistema y la respuesta desaparece. Añade una señal que no sea color: un borde, un desplazamiento pequeño, un cambio de grosor.

Las sombras animadas no existen. Elevar un elemento con box-shadow al pasar el ratón no se ve. Si la elevación es información, necesita un borde.

forced-color-adjust: none desactiva la sustitución en un elemento. Úsalo solo cuando el color sea imprescindible para el significado, como en una leyenda de un gráfico. Usarlo para conservar tu marca es exactamente lo que el modo intenta impedir.

prefers-contrast es la preferencia adyacente, con valores more, less, custom y no-preference. Para animación importa sobre todo en las opacidades intermedias: un elemento que pasa por opacidad 0,4 durante una transición es ilegible para quien pidió más contraste. La versión de contraste alto debe acortar el tramo translúcido o eliminarlo.

@media (prefers-contrast: more) {
  .desvanecido { --opacidad-intermedia: 0.85; }
  .separador { border-width: 2px; }
}

Destellos

Este es un riesgo distinto y hay que tratarlo aparte, porque el mecanismo no tiene nada que ver con el vestibular y las consecuencias son más graves: un patrón de destellos puede desencadenar una crisis en una persona con epilepsia fotosensible.

El umbral de WCAG es concreto. Un contenido no puede destellar más de tres veces por segundo, salvo que los destellos estén por debajo de los umbrales definidos. Un destello, en la definición del criterio, es un par de cambios opuestos de luminancia relativa de al menos el 10% del máximo, donde el estado más oscuro está por debajo de 0,80 de luminancia relativa, y donde el área afectada supera una porción del campo visual. Ese área se define como más del 25% de cualquier campo visual de diez grados en pantalla, lo que WCAG traduce a algo del orden de 341 por 256 píxeles combinados en una pantalla de referencia. Y hay un umbral adicional y más estricto para los destellos que involucran rojo saturado, porque son especialmente provocadores.

Traducido a cosas que se escriben:

  • Ningún parpadeo por encima de tres por segundo. Un @keyframes que alterna opacidad cada ciento cincuenta milisegundos son más de tres por segundo.
  • Ninguna alternancia de alto contraste sobre áreas grandes. Un fondo que pasa de negro a blanco en bucle es el caso de manual.
  • Cuidado con lo generado: efectos de canvas, shaders, vídeo, y sobre todo GIF y vídeo subidos por usuarios, que no controlas.
  • El rojo saturado alternando exige más margen todavía.

Para verificar, existe la Photosensitive Epilepsy Analysis Tool, una herramienta gratuita del Trace Center que analiza un vídeo fotograma a fotograma contra los umbrales. Si tu producto tiene efectos generados —un juego, una visualización, un editor— grabar treinta segundos y pasarlos por ahí es la única verificación seria. Mirar y decir “no parpadea tanto” no lo es: el umbral está por debajo de lo que una persona sin la condición percibe como molesto.

🛑
Los destellos no se negocian con prefers-reduced-motion

Un destello por encima del umbral es un riesgo médico, no una preferencia estética, y la consulta de movimiento reducido no lo cubre porque no es un problema de movimiento. No hay una versión aceptable de un contenido que destella siete veces por segundo detrás de una preferencia. Simplemente no puede existir en tu producto.

La auditoría de movimiento

Una hoja de comprobación ejecutable sobre un producto existente. Cada punto es verificable en minutos y detecta un fallo concreto de este nivel.

Sin tocar nada. Carga la página, no interactúes y cuenta hasta seis. ¿Sigue moviéndose algo? Si sí, comprueba que hay un control para pararlo. Es el criterio 2.2.2 y es el incumplimiento más frecuente.

Con la preferencia activada. Emula movimiento reducido y recorre las pantallas principales. Para cada animación que desaparece, pregunta qué información se ha perdido. Comprueba que no queda nada a medias: elementos con opacidad intermedia, paneles fuera de sitio, contenido nunca revelado.

Solo con teclado. Tabula por cada pantalla sin tocar el ratón. ¿El foco se va alguna vez a un sitio invisible? ¿Alguna vez desaparece al cerrar algo? ¿Se te queda el foco dentro de un panel que se está moviendo?

Con la ruedecilla parada. Desactiva JavaScript y recarga. ¿Sigue habiendo contenido? Todo lo que se revela al hacer scroll debe estar visible sin JavaScript, no oculto para siempre.

Con el zoom al 400%. Reduce la ventana o amplía. Los elementos que se mueven con posiciones absolutas calculadas suelen acabar fuera de la pantalla.

Con colores forzados. Actívalo y comprueba que todos los cambios de estado siguen siendo visibles. Los que se comunicaban solo con color, no lo son.

Midiendo el movimiento grande. Para cada animación, estima qué porcentaje del viewport ocupa el área en movimiento y en qué eje se mueve. Todo lo que supere el veinte por ciento de la pantalla o contenga escala, rotación o paralaje va a la lista de riesgo y necesita versión reducida diseñada, no apagado automático.

Con el lector de pantalla. Recorre una pantalla con revelado por scroll con VoiceOver o NVDA activo. ¿Se anuncia contenido que aún no está visible? ¿Se anuncian los mensajes al aparecer o al terminar de aparecer?

La accesibilidad del movimiento es la única parte de la accesibilidad que también es una decisión de rendimiento

Merece la pena notar una coincidencia que no es casual y que puedes usar para conseguir presupuesto cuando el argumento ético no basta: casi todo lo que hace daño en términos de accesibilidad del movimiento es también lo más caro de ejecutar. El paralaje a pantalla completa recalcula posiciones en cada evento de scroll y repinta un área enorme. El backdrop-filter animado obliga al compositor a leer, filtrar y recomponer el fondo en cada fotograma. El vídeo de fondo en bucle mantiene un decodificador activo y consume batería durante toda la sesión. El brillo que recorre un esqueleto anima un degradado sobre gran superficie, que no se puede promocionar a una capa y repinta constantemente. El confeti son doscientos elementos con doscientas transformaciones por fotograma. Y en la dirección contraria pasa lo mismo: las transiciones de opacidad cortas, que son las seguras, son también las que el compositor ejecuta sin tocar el hilo principal, con coste prácticamente nulo. Esta correlación no es una casualidad afortunada, tiene una causa común: lo que hace daño es lo que ocupa mucho campo visual y cambia mucho, y eso es exactamente la definición de lo que cuesta píxeles. La consecuencia estratégica es que no tienes que elegir entre las dos cosas ni presentarlas como dos peticiones distintas al mismo comité. La lista de animaciones que hay que revisar por accesibilidad y la lista de animaciones que hay que revisar por rendimiento son, en la práctica, la misma lista ordenada por el mismo criterio, y arreglar una entrada arregla las dos. Quien entiende esto deja de pelear dos batallas y pelea una sola, con el doble de argumentos y con datos medibles para respaldar la parte que a la gente le cuesta menos discutir.