Técnica CSS WCAG 2.2
C39Respetar la preferencia de movimiento reducido con CSS
Nombre oficial en el W3C: Usar la consulta de medios prefers-reduced-motion de CSS para evitar el movimiento
En pocas palabras
Los sistemas operativos tienen una opción para reducir el movimiento en pantalla. La consulta CSS prefers-reduced-motion permite saber si la persona la ha activado. En ese caso, la web quita o suaviza las animaciones que aparecen al pulsar, desplazarse o pasar el ratón.
Por qué es importante
A algunas personas el movimiento en pantalla les provoca mareo, náuseas o dolor de cabeza. Les pasa, por ejemplo, a quienes tienen trastornos vestibulares (problemas del equilibrio en el oído interno).
A otras, como personas con déficit de atención, les distrae y les impide concentrarse. Un fondo que se mueve al desplazar o un panel que entra girando puede obligarlas a abandonar la página.
Cómo se hace
- Localice las animaciones que se activan al interactuar: paneles que se deslizan, efectos al desplazar, tarjetas que se inclinan, carruseles.
- Añada un bloque
@media (prefers-reduced-motion: reduce)en el CSS. - Dentro, quite los desplazamientos, giros y zooms. Puede dejar cambios suaves, como un fundido corto.
- Otra opción es al revés: estilos sin movimiento por defecto y animaciones solo dentro de
@media (prefers-reduced-motion: no-preference). - En animaciones hechas con JavaScript, consulte la misma preferencia con
matchMedia.
Ejemplo práctico
Muchas tiendas online usan paneles que entran deslizándose, tarjetas que rebotan o fondos que se mueven al desplazar. Con prefers-reduced-motion, la web respeta el ajuste «reducir movimiento» del sistema (criterio 2.3.3 Animación desde interacciones).
Así no: Panel de ofertas que entra girando y rebotando
Al pulsar el botón, el panel entra desde la izquierda con giro y rebote durante 1,2 segundos. Ocurre aunque la persona haya activado en su sistema la opción de reducir el movimiento. La web no consulta esa preferencia.

La demostración contiene, a propósito, el error de accesibilidad que se explica.
Ver el código del ejemplo incorrecto
<style>
.panel { margin-top: 12px; padding: 4px 12px; background: #f3eef8; border-left: 4px solid #744E9A; opacity: 0; visibility: hidden; transform: translateX(-120%) rotate(-8deg); transition: transform 1.2s cubic-bezier(.5, 1.8, .5, 1), opacity 1.2s, visibility 1.2s; }
.panel.abierto { opacity: 1; visibility: visible; transform: none; }
</style>
<button type="button" id="btn-ofertas" aria-expanded="false" aria-controls="ofertas">Ver ofertas de la semana</button>
<div class="panel" id="ofertas">
<p>Aceite de oliva virgen extra, 5 l: 29,90 €</p>
<p>Queso manchego curado, 1 kg: 14,50 €</p>
</div>
<script>
const boton = document.getElementById('btn-ofertas');
const panel = document.getElementById('ofertas');
boton.addEventListener('click', () => {
const abierto = panel.classList.toggle('abierto');
boton.setAttribute('aria-expanded', abierto);
});
</script>Así sí: Sin desplazamiento cuando se pide movimiento reducido
Se añade la consulta @media (prefers-reduced-motion: reduce). Elimina el desplazamiento y el giro, y deja solo un fundido breve. Para ver la diferencia, active «Reducir movimiento» en el sistema o emúlelo en las herramientas del navegador (panel Rendering).
Pruébelo aquí:
Ver el código del ejemplo correcto
<style>
.panel { margin-top: 12px; padding: 4px 12px; background: #f3eef8; border-left: 4px solid #744E9A; opacity: 0; visibility: hidden; transform: translateX(-120%) rotate(-8deg); transition: transform 1.2s cubic-bezier(.5, 1.8, .5, 1), opacity 1.2s, visibility 1.2s; }
.panel.abierto { opacity: 1; visibility: visible; transform: none; }
@media (prefers-reduced-motion: reduce) {
.panel { transform: none; transition: opacity .2s, visibility .2s; }
}
</style>
<button type="button" id="btn-ofertas" aria-expanded="false" aria-controls="ofertas">Ver ofertas de la semana</button>
<div class="panel" id="ofertas">
<p>Aceite de oliva virgen extra, 5 l: 29,90 €</p>
<p>Queso manchego curado, 1 kg: 14,50 €</p>
</div>
<script>
const boton = document.getElementById('btn-ofertas');
const panel = document.getElementById('ofertas');
boton.addEventListener('click', () => {
const abierto = panel.classList.toggle('abierto');
boton.setAttribute('aria-expanded', abierto);
});
</script>Cómo comprobarlo
Errores frecuentes en auditorías
- Añadir la consulta para las animaciones CSS, pero no para las de JavaScript (efectos de aparición al desplazar, parallax, GSAP). Estas siguen moviéndose.
- Poner
animation: noneen la consulta y dejar el elemento en su estado inicial invisible. El contenido desaparece. - Aplicar la consulta solo a algunos componentes. Se olvidan efectos al pasar el ratón o al desplazar, como tarjetas que se inclinan o fondos que se mueven.
- Dejar carruseles que se deslizan aunque se pida movimiento reducido. Deberían cambiar a un fundido o a un cambio directo.
Ver el texto completo del W3C (traducción al español)
Esta es una traducción no oficial al español de la técnica C39 de Techniques for WCAG 2.2, del W3C. Puede contener errores. El único documento oficial y normativo es la versión original en inglés, publicada en el sitio web del W3C.
Aplicabilidad
CSS que provoca movimiento desencadenado por las interacciones del usuario.
Descripción
El objetivo de esta técnica es permitir que los usuarios eviten que se muestren animaciones (incluidas las animaciones con movimiento) en las páginas web, mediante el uso de la consulta de medios (media query) prefers-reduced-motion de CSS.
Algunos usuarios sufren distracción o náuseas con el contenido animado. Por ejemplo, si al desplazar una página los elementos se mueven (más allá del movimiento esencial asociado al desplazamiento del contenido, que está bajo el control del usuario), puede desencadenar trastornos vestibulares.
Las consultas de medios que activan o desactivan de forma selectiva las animaciones basadas en CSS según las preferencias del sistema operativo o del agente de usuario permiten a los usuarios evitar esos desencadenantes.
El documento de comprensión de Animaciones desde interacciones incluye enlaces para cambiar el ajuste de «movimiento reducido».
Ejemplos
Consulta de medios prefers-reduced-motion de CSS
Los usuarios pueden indicar en su sistema su preferencia de movimiento para las interfaces, y la consulta de medios prefers-reduced-motion de CSS respetará esa elección. A continuación puede aplicarse CSS para desactivar ese movimiento para los usuarios que así lo soliciten.
/* CSS for the motion effect */
@media (prefers-reduced-motion: reduce) {
/* CSS to disable motion goes here */
}
Ejemplo práctico de la consulta de medios «prefers-reduced-motion» de CSS
Como alternativa, es posible seguir el planteamiento inverso: definir estilos estáticos y, después, incluir una consulta de medios que solo se aplique cuando el usuario no haya establecido la preferencia de movimiento reducido.
/* "Static" CSS styles */
@media (prefers-reduced-motion: no-preference) {
/* CSS for the motion effect goes here */
}
Pruebas
Procedimiento
Para cada elemento interactivo que desencadena una animación con movimiento como resultado de una interacción del usuario:
- Activar el ajuste de movimiento reducido en el sistema;
- Comprobar que la animación con movimiento es esencial;
- Comprobar que la animación con movimiento se suprime.
Resultados esperados
- La comprobación n.º 2 o la n.º 3 es verdadera.
Cómo lo comprobamos en ADDAW
En cada auditoría de ADDAW revisamos esta técnica página a página y le entregamos los errores con capturas y la forma de corregirlos.
Basado en la técnica C39 del W3C (WCAG 2.2). Explicación y ejemplos: ADDAW. Traducción no oficial del texto del W3C © W3C, licencia de documentos del W3C. ¿Ha visto un error? Escríbanos.