Prefers Reduced Motion para mejorar accesibilidad web

Mejorar la accesibilidad para personas que necesiten o quieran visitar nuestra web con animaciones desactivadas media Prefers Reduced Motion
Prefers Reduced Motion para mejorar accesibilidad web

Deshabilitar animaciones según preferencias del usuario

CSS

CSS dispone de una media para poder saber si el usuario tiene habilitado o no las animaciones

@media screen and (prefers-reduced-motion: reduce) {}

Con el uso de variables CSS se puede fácilmente cambiar los valores relacionados con time. Por defecto se le pueden asignar valores, y caso que el usuario tenga deshabilitadas las animaciones, setearlas a 0

:root {
  --t-delay-btn: .3s;
  --t-duration-btn: .5s;
}
@media screen and (prefers-reduced-motion: reduce) {
  :root {
    --t-delay-btn: 0s;
    --t-duration-btn: 0s;
  }
}
.btn {
  // otras definiciones
  transition: all var(--t-duration-btn) linear var(--t-delay-btn);
  &:hover,
  &:focus {
    // otras definiciones
    transition: all var(--t-duration-btn) linear var(--t-delay-btn);
  }
}

El ejemplo es aplicado a transitions pero también puede aplicarse a animations

Javascript

Desde Javascript también es posible poder consultar las preferencias del usuario sobre animaciones

const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");

En el ejemplo, se usar la librería swiperjs

Se crea un objeto para guardar las settings con las que incializaremos Swiper

const swiperSettings = {
  pagination: {
    el: ".swiper-pagination",
    clickable: true
  },
  navigation: {
    nextEl: ".swiper-button-next",
    prevEl: ".swiper-button-prev"
  },
  scrollbar: {
    el: '.swiper-scrollbar',
  },
};

Como puede verse, no se especifica el efecto en la animación ni el tiempo de duración, más adelante se definen estas propiedades en función de la configuración del propio equipo del cliente

if (!mediaQuery || mediaQuery.matches) {
  animationsDisabled(swiperSettings);
} else {
  animationsEnable(swiperSettings);
}

Se trata de un if que nos determinará la configuración del usuario. Según el caso, pasaremos una u otra configuración del usuario

const animationsDisabled = settings => {
  console.log('no animation');
  settings.effect = "fade";
  settings.speed = 0;
}
const animationsEnable = settings => {
  console.log('animation');
  settings.effect = "slide";
  settings.speed = 300;
}

Después de esto, ya si creamos la instancia de Swiper

let swiper = new Swiper(".swiper", swiperSettings);

Si se produce cambio en la configuración del usuario, entonces, quitamos Swiper y volvemos a instanciarlo. Para esto, registramos un evento change sobre la @media

mediaQuery.addEventListener("change", () => {
  swiper.destroy();
  if (mediaQuery.matches) {
    animationsDisabled(swiperSettings);
  } else {
    animationsEnable(swiperSettings);
  }
  swiper = new Swiper(".swiper", swiperSettings);
});

Recursos de interés

Mi GitHub

Mi Codepen

En este ejemplo puede verse detalles CSS así como se configura en el ordenador la opción de no animaciones

https://a11y-101.com/development/reduced-motion

Ejemplo con Jasvascript

https://since1979.dev/respecting-prefers-reduced-motion-with-javascript-and-react/