usePrefersReducedMotion

usePrefersReducedMotion — это специализированный хук из библиотеки Chakra UI, который позволяет определять предпочтения пользователя относительно анимаций на уровне операционной системы. Он является частью подхода доступности (accessibility) и особенно полезен для создания интерфейсов, которые учитывают ограничения или предпочтения пользователей с повышенной чувствительностью к анимации.


Основные возможности

  • Определение, включены ли у пользователя настройки уменьшенной анимации в системе.
  • Динамическая адаптация компонентов и анимаций без необходимости ручного управления состояниями.
  • Совместимость с любыми CSS-анимациями, Transition API и библиотеками для анимаций, интегрируемыми с React.

Импорт и базовое использование

import { usePrefersReducedMotion } from '@chakra-ui/react';

function ExampleComponent() {
  const prefersReducedMotion = usePrefersReducedMotion();

  return (
    <div>
      {prefersReducedMotion
        ? 'Анимации отключены'
        : 'Анимации активны'}
    </div>
  );
}

Пояснение:

  • Хук возвращает булево значение: true если пользователь предпочитает минимальные анимации, false если ограничений нет.
  • Это значение можно использовать для условного рендера анимаций, переходов и сложных эффектов.

Применение с компонентами Chakra UI

Chakra UI предоставляет множество компонентов с анимационными эффектами: Collapse, ScaleFade, Slide, Fade. usePrefersReducedMotion позволяет их адаптировать под настройки пользователя:

import { Collapse, Button, usePrefersReducedMotion } from '@chakra-ui/react';
import { useState } from 'react';

function CollapsibleSection() {
  const [isOpen, setIsOpen] = useState(false);
  const prefersReducedMotion = usePrefersReducedMotion();

  return (
    <>
      <Button onCl ick={() => setIsOpen(!isOpen)}>
        Показать / Скрыть
      </Button>
      <Collapse
        in={isOpen}
        animateOpacity={!prefersReducedMotion} // отключаем анимацию если пользователь выбрал reduced motion
      >
        <div>Содержимое секции с адаптивной анимацией</div>
      </Collapse>
    </>
  );
}

Ключевые моменты:

  • animateOpacity или аналогичные пропсы можно отключать, основываясь на значении prefersReducedMotion.
  • Этот подход позволяет избежать резких мерцаний или сложных переходов для пользователей с ограничениями.

Интеграция с пользовательскими анимациями

Для пользовательских анимаций через framer-motion или CSS-переходы:

import { motion } from 'framer-motion';
import { usePrefersReducedMotion } from '@chakra-ui/react';

function AnimatedBox() {
  const prefersReducedMotion = usePrefersReducedMotion();

  return (
    <motion.div
      animate={prefersReducedMotion ? {} : { x: 100, opacity: 1 }}
      transition={prefersReducedMotion ? {} : { duration: 0.5 }}
      style={{ width: 100, height: 100, backgroundColor: 'tomato' }}
    />
  );
}

Объяснение:

  • Когда prefersReducedMotion равен true, анимации полностью отключаются.
  • Это особенно важно для плавных пользовательских интерфейсов, где анимация может вызвать дискомфорт.

Практические советы

  1. Всегда проверять prefersReducedMotion для сложных анимаций. Даже короткие анимации могут вызывать дискомфорт у некоторых пользователей.
  2. Комбинировать с CSS-переменными или стилями. Например, менять transition или animation-duration на ноль.
  3. Использовать вместе с Theme: можно задать глобальные настройки для всех анимационных компонентов Chakra UI, используя тему.
import { extendTheme } from '@chakra-ui/react';

const theme = extendTheme({
  styles: {
    global: (props) => ({
      '*': {
        transitionDuration: props.prefersReducedMotion ? '0ms' : undefined,
      },
    }),
  },
});
  1. Тестирование: включить режим «уменьшенная анимация» в системных настройках macOS или Windows, чтобы проверить реакцию интерфейса.

Важные нюансы

  • usePrefersReducedMotion опирается на медиа-запрос @media (prefers-reduced-motion: reduce).
  • На мобильных устройствах поддержка может отличаться, важно тестировать на iOS и Android.
  • Хук работает динамически — если пользователь изменяет настройки в процессе работы приложения, состояние хука обновляется автоматически.

usePrefersReducedMotion позволяет создавать более доступные и комфортные интерфейсы, одновременно упрощая управление анимациями и обеспечивая соответствие стандартам WCAG 2.1. Адаптация компонентов и пользовательских анимаций к этому хуку повышает качество UX для широкой аудитории.