Windows, macOS, iOS y Android tienen una opción de accesibilidad para «reducir movimiento». La usan personas a las que los desplazamientos y los zooms de la pantalla les producen mareo o náusea (por ejemplo, con trastornos vestibulares), y también quien simplemente prefiere una interfaz más quieta. CSS puede leer esa preferencia con prefers-reduced-motion. Bien aplicada, no significa quitar toda animación.
También te puede interesar
El código
<p class="estado"><span class="giro" aria-hidden="true"></span> Guardando…</p> <a class="tarjeta" href="#">Una tarjeta que se levanta al pasar el ratón</a>
body { font-family: system-ui, sans-serif; }
.giro {
display: inline-block;
width: 18px; height: 18px;
border: 3px solid #c9d6e4;
border-top-color: #1e64af;
border-radius: 50%;
vertical-align: middle;
animation: girar 0.8s linear infinite;
}
@keyframes girar { to { rotate: 1turn; } }
@keyframes latir { 50% { opacity: 0.35; } }
.tarjeta {
display: block;
margin-top: 16px;
padding: 16px;
border: 1px solid #d5dde6;
border-radius: 10px;
transition: translate 0.3s, box-shadow 0.3s;
}
.tarjeta:hover { translate: 0 -6px; box-shadow: 0 10px 24px rgb(15 31 51 / 0.15); }
@media (prefers-reduced-motion: reduce) {
/* el aviso de «guardando» se queda, pero late en vez de girar */
.giro { animation: latir 1.6s ease-in-out infinite; }
/* la tarjeta cambia de sombra sin moverse */
.tarjeta { transition: box-shadow 0.3s; }
.tarjeta:hover { translate: none; }
}Con la preferencia normal, el indicador gira (animation-name = girar en los tres navegadores). Para ver la otra cara, emulamos «reducir movimiento» en Chromium, Firefox y WebKit y medimos lo mismo:
medido con la preferencia emuladachromium normal: animación girar, transición 0.3s, 0.3s | reducir: animación latir, transición 0.3s firefox normal: animación girar, transición 0.3s, 0.3s | reducir: animación latir, transición 0.3s webkit normal: animación girar, transición 0.3s, 0.3s | reducir: animación latir, transición 0.3s
En los tres, con «reducir movimiento» el indicador cambia a latir (un cambio de opacidad, sin desplazamiento) y la tarjeta conserva solo la transición de la sombra.
Qué quitar y qué conservar
- Quita lo que mueve cosas grandes por la pantalla: desplazamientos suaves largos, efectos de paralaje, zooms, carruseles que avanzan solos, fondos animados y transiciones de página que deslizan.
- Conserva, con otra forma, lo que comunica algo: un indicador de «cargando» o «guardando», un aviso que aparece, el cambio de estado de un botón. Cámbialos por un fundido o un cambio de color.
- No uses
animation: none !importantpara todo: con eso también desaparecen avisos que la persona necesita ver.
El patrón al revés: animar solo si no se pidió lo contrario
/* Sin animación por defecto */
.banner { opacity: 1; }
/* Solo quien no pidió reducir movimiento la ve */
@media (prefers-reduced-motion: no-preference) {
.banner { animation: entrar 0.6s ease-out; }
}Escribir las animaciones dentro de @media (prefers-reduced-motion: no-preference) es más seguro: si un navegador no conoce la consulta, se queda quieto, que es el lado bueno del error.
Un caso real: el iPhone que pedía menos movimiento
En decodigo.com, las infografías animadas de las noticias respetan esta preferencia: si la persona la pide, muestran el dibujo final, quieto. En pruebas con un iPhone real, Safari decía que la preferencia estaba activada (reduce) aunque la opción «Reducir movimiento» de Accesibilidad estaba apagada, así que las infografías no se animaban en ese teléfono. No encontramos por qué el sistema lo informaba así, pero la lección es clara: tú no decides qué recibe cada persona. Diseña la versión sin movimiento para que también se vea completa y se entienda, porque alguien la va a recibir.
Cada fragmento de HTML de esta página pasó por el Nu Html Checker 26.11.4 (el validador del W3C) y cada resultado se pintó y se midió en Chromium, Firefox y WebKit antes de publicarla. Prueba tus cambios en el editor de HTML y CSS o aprende desde cero con el curso.