Reduce Motion в мобильных приложениях: суть, настройки уменьшения движения

Автор: IT Sectr Опубликовано: 2026-05-16 Время чтения: 12 мин

Reduce Motion — accessibility-функция операционных систем и браузеров, которая отключает или сокращает анимацию интерфейса для предотвращения дискомфорта у пользователей с вестибулярными нарушениями. В iOS настройка находится в Settings > Accessibility > Motion > Reduce Motion и отключает параллакс, анимацию переходов между экранами и эффекты иконок. В Android аналогичная опция «Удалить анимацию» расположена в Настройках > Специальные возможности. По данным W3C WCAG 2.2, чрезмерная анимация может вызывать тошноту, головокружение и мигрень у 15–35% людей с vestibular disorders.

Главное

  • Reduce Motion — accessibility-настройка, отключающая анимацию интерфейса для комфорта пользователей с vestibular disorders
  • iOS Reduce Motion — в Settings > Accessibility > Motion: отключает параллакс, переходы иконок и эффекты сообщений
  • Android — «Удалить анимацию» в Настройках > Специальные возможности; отключает масштабирование и переходы
  • CSS prefers-reduced-motion — медиа-функция для веб-разработчиков: отключает CSS-анимацию при системной настройке
  • WCAG 2.2 — критерий 2.3.3 предписывает отключать анимацию от взаимодействия по умолчанию

Что такое Reduce Motion в accessibility?

Reduce Motion — системная настройка, предписывающая операционной системе, браузеру и приложениям минимизировать или полностью отключить анимацию, перемещение, масштабирование и параллакс-эффекты. Функция предназначена для людей с вестибулярными расстройствами (vestibular disorders), при которых движущиеся элементы интерфейса вызывают тошноту, головокружение, дезориентацию и мигрень.

Вестибулярная система внутреннего уха отвечает за чувство равновесия и ориентации в пространстве. Когда глаза видят движение на экране, а вестибулярный аппарат не ощущает соответствующего перемещения тела, возникает сенсорный конфликт. Этот конфликт запускает вегетативную реакцию: тошноту, холодный пот, головокружение. По данным Vestibular Disorders Association, около 35% людей старше 40 лет испытывают дискомфорт от motion-эффектов в интерфейсах.

Ключевое отличие Reduce Motion от простого отключения анимации — системный уровень. Включённая настройка передаётся всем приложениям и веб-сайтам через API ОС или CSS-медиа-функцию prefers-reduced-motion. Разработчику не нужно гадать, хочет ли пользователь анимацию — ОС сообщает об этом. Это часть подхода progressive enhancement: анимация — это улучшение, а не обязательный элемент.

Какие эффекты отключает Reduce Motion

Reduce Motion влияет на параллакс-эффекты (смещение фона при наклоне устройства), анимацию переходов между экранами (push, slide, fade), масштабирование иконок при нажатии, эффекты сообщений (SMS-пузырьки), анимацию загрузки (spinner, skeleton, progress bar animation), параллакс в играх и веб-эффекты parallax scrolling. Статические изображения и видео не затрагиваются.

Тип анимацииiOS Reduce MotionAndroid Remove AnimationCSS prefers-reduced-motion
Параллакс обоевОтключаетОтключаетN/A
Переходы между экранамиЗаменяет на fadeОтключаетCSS transitions
Анимация иконокОтключаетНе влияетCSS animations
Spinner загрузкиНе влияетОтключаетCSS animations
Skeleton screensНе влияетЗаменяет на staticCSS animations

Кому нужен Reduce Motion

Основная аудитория Reduce Motion — люди с vestibular disorders (болезнь Меньера, лабиринтит, BPPV), мигренью (особенно с аурой), kinetosis (укачивание в транспорте) и некоторыми формами epilepsy. Функция также полезна для пожилых пользователей — возрастные изменения вестибулярного аппарата повышают чувствительность к motion, и для пользователей с СДВГ — движущиеся элементы отвлекают от чтения.

Reduce Motion в iOS: настройка и системные эффекты

В iOS Reduce Motion находится в Settings > Accessibility > Motion и включает три опции: Reduce Motion (основной переключатель), Auto-Play Message Effects (автовоспроизведение эффектов iMessage) и Auto-Play Video Previews (автовоспроизведение видео в App Store). Reduce Motion — самый мощный: он отключает параллакс обоев, анимацию открытия приложений (zoom), переходы между экранами (push заменяется на cross-fade) и эффекты иконок на домашнем экране.

Технически iOS реализует Reduce Motion на уровне UIKit через UIView animations и UIViewControllerAnimatedTransitioning. При включённой настройке UIView.animate длительностью > 0 сокращается до 0.01 сек, а UIViewController.transitionDuration возвращает 0. Для параллакса iOS отключает UIInterpolatingMotionEffect на UIWindow. Разработчик может проверить состояние через UIAccessibility.isReduceMotionEnabled.

Проверка Reduce Motion в iOS-приложении

Разработчик может адаптировать анимацию в iOS под Reduce Motion: заменить сложные переходы на fade-эффекты, отключить параллакс в кастомных UI-компонентах и сократить длительность анимаций. SwiftUI предоставляет специальный модификатор .animation(nil) при активном reduceMotion.

swift
import UIKit

class MotionManager {

    // Проверка состояния Reduce Motion
    static var isReduceMotionEnabled: Bool {
        return UIAccessibility.isReduceMotionEnabled
    }

    // Безопасная анимация с учётом Reduce Motion
    static func animate(
        duration: TimeInterval,
        delay: TimeInterval = 0,
        options: UIView.AnimationOptions = [],
        animations: @escaping () -> Void,
        completion: ((Bool) -> Void)? = nil
    ) {
        let adjustedDuration = isReduceMotionEnabled
            ? 0.01
            : max(duration, 0.01)
        UIView.animate(
            withDuration: adjustedDuration,
            delay: delay,
            options: options,
            animations: animations,
            completion: completion
        )
    }
}

// SwiftUI — модификатор для Reduce Motion
import SwiftUI

struct MotionAwareView: View {
    @Environment(\.accessibilityReduceMotion)
    private var reduceMotion

    @State private var isAnimating = false

    var body: some View {
        Circle()
            .scaleEffect(isAnimating ? 1.2 : 1.0)
            .animation(
                reduceMotion
                    ? nil
                    : .easeInOut(duration: 1.0).repeatForever(),
                value: isAnimating
            )
            .onAppear { isAnimating = true }
    }
}

// Подписка на изменение Reduce Motion
NotificationCenter.default.addObserver(
    self,
    selector: #selector(motionStatusChanged),
    name: UIAccessibility.reduceMotionStatusDidChangeNotification,
    object: nil
)

Класс MotionManager проверяет isReduceMotionEnabled и адаптирует длительность анимации: при активном Reduce Motion длительность сокращается до 0.01 сек (фактически мгновенно). SwiftUI модификатор .animation(nil) полностью отключает анимацию при reduceMotion == true. Подписка на reduceMotionStatusDidChangeNotification позволяет динамически переключать анимацию без перезагрузки приложения.

Auto-Play Message Effects в iMessage

Отдельная опция iOS — Auto-Play Message Effects — управляет воспроизведением эффектов в iMessage: balloon-анимацией, конфетти, лазерами и фейерверками. При включённом Reduce Motion эффекты iMessage автоматически отключаются. Разработчик может проверить эту опцию через UIAccessibility.isReduceMotionEnabled — отдельного API для Message Effects нет, они привязаны к общей настройке.

Удалить анимацию в Android: Developer Options и Accessibility

В Android настройка «Удалить анимацию» (Remove animations) находится в двух местах: Настройки > Специальные возможности > Удалить анимацию (для accessibility-настроек) и Параметры разработчика > Масштаб анимации (для разработчиков). Accessibility-версия отключает все системные анимации, включая переходы между экранами, анимацию открытия приложений и эффекты загрузки. Developer Options позволяют уменьшить масштаб в 0.5x, 0.1x или отключить полностью.

Технически Android реализует отключение анимации через системные properties: window_animation_scale, transition_animation_scale и animator_duration_scale. При accessibility-настройке все три получают значение 0. Системный Launcher и системные приложения проверяют эти значения. Для сторонних приложений Android рекомендует использовать Jetpack compose и View system, которые автоматически считывают системную настройку через AnimationScaleObserver.

Проверка в Android-приложении

Разработчик может проверить состояние анимации в Android через Settings.Global и адаптировать UI. Jetpack Compose предоставляет AnimationScaleObserver для автоматической подстройки. Ключевое значение — animator_duration_scale: если 0, анимация отключена полностью.

kotlin
import android.content.Context
import android.provider.Settings
import android.database.ContentObserver
import android.os.Handler
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.runtime.getValue

class AndroidMotionHelper {

    // Проверка отключения анимации
    fun isAnimationDisabled(context: Context): Boolean {
        return try {
            Settings.Global.getFloat(
                context.contentResolver,
                Settings.Global.ANIMATOR_DURATION_SCALE
            ) == 0f
        } catch (e: Settings.SettingNotFoundException) {
            false
        }
    }

    // Наблюдение за изменением анимации (ContentObserver)
    fun observeAnimationScale(
        context: Context,
        onChange: (Boolean) -> Unit
    ): ContentObserver {
        val observer = object : ContentObserver(Handler()) {
            override fun onChange(selfChange: Boolean) {
                onChange(isAnimationDisabled(context))
            }
        }
        context.contentResolver.registerContentObserver(
            Settings.Global.getUriFor(
                Settings.Global.ANIMATOR_DURATION_SCALE
            ),
            false,
            observer
        )
        return observer
    }
}

// Jetpack Compose — анимация с учётом настроек
@Composable
fun MotionAwareAnimation(enabled: Boolean) {
    val context = androidx.compose.ui.platform.LocalContext.current
    val noMotion = AndroidMotionHelper().isAnimationDisabled(context)

    val scale by animateFloatAsState(
        targetValue = if (enabled) 1f else 0f,
        animationSpec = if (noMotion) {
            androidx.compose.animation.core.tween(durationMillis = 0)
        } else {
            androidx.compose.animation.core.spring()
        },
        label = "scale"
    )
    // UI с анимацией
}

Класс AndroidMotionHelper проверяет ANIMATOR_DURATION_SCALE через Settings.Global, предоставляет ContentObserver для отслеживания изменений и позволяет Jetpack Compose анимациям адаптироваться: при отключённой анимации durationMillis = 0 (мгновенное применение). Для View-системы используйте ViewPropertyAnimator.withLayer() и проверку isAnimationDisabled() перед запуском анимации.

Разница между Accessibility и Developer Options

Accessibility-настройка «Удалить анимацию» в Android — единственный способ для обычного пользователя отключить анимацию. Developer Options (параметры разработчика) предназначены только для разработчиков и могут быть скрыты. Accessibility-настройка гарантированно передаётся всем приложениям через системный API. Разработчику следует ориентироваться именно на AccessibilityManager, а не на Developer Options.

CSS prefers-reduced-motion: медиа-функция для веба

CSS-медиа-функция prefers-reduced-motion позволяет веб-разработчикам отключать или заменять анимацию, когда пользователь включил Reduce Motion в операционной системе. Браузер передаёт значение reduce при активной системной настройке, no-preference — если настройка не изменена. Поддерживается всеми современными браузерами с 2020 года: Chrome 74+, Safari 10.3+, Firefox 64+, Edge 79+.

Рекомендация MDN и W3C — всегда задавать prefers-reduced-motion: reduce вместе с анимациями. Пользователь, включивший Reduce Motion, не должен видеть пульсации, параллакс, автопроигрывание каруселей и skeleton-загрузку. Вместо анимации можно показывать статический контент или использовать CSS transition с минимальной длительностью. Ниже приведён пример полной адаптации.

Адаптация веб-страницы через prefers-reduced-motion

При prefers-reduced-motion: reduce веб-страница должна: отключить CSS анимации (@keyframes), заменить CSS transitions на мгновенные изменения, остановить JavaScript-анимации (requestAnimationFrame), отключить parallax scrolling, остановить карусели и слайдеры, отключить skeleton-эффекты и заменить spinner на статический индикатор.

css
/* Базовые анимации (no-preference) */
.spinner {
    width: 32px;
    height: 32px;
    border: 3px solid #e0e0e0;
    border-top-color: #0066CC;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

.skeleton {
    background: linear-gradient(
        90deg,
        #f0f0f0 25%,
        #e8e8e8 37%,
        #f0f0f0 63%
    );
    background-size: 400% 100%;
    animation: shimmer 1.4s ease infinite;
}

.parallax-bg {
    transform: translateZ(-1px) scale(1.5);
    transition: transform 0.3s ease-out;
}

/* Reduce Motion: отключаем всё */
@media (prefers-reduced-motion: reduce) {
    .spinner {
        animation: none;
        border-top-color: #0066CC;
    }

    .skeleton {
        animation: none;
        background: #f0f0f0;
    }

    .parallax-bg {
        transform: none;
        transition: none;
    }

    .carousel {
        scroll-behavior: auto;
        overflow-x: auto;
    }

    .fade-in {
        opacity: 1;
        transform: none;
    }

    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

@keyframes shimmer {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

В примере CSS используется глобальный сброс анимации при prefers-reduced-motion: reduce: все анимации и переходы получают duration 0.01ms и iteration-count 1. Отдельно переопределены spinner (статическая граница), skeleton (серый фон без мерцания), parallax (отключён) и carousel (scroll-behavior: auto вместо smooth). Универсальный селектор * — страховка для всех элементов.

JavaScript-детекция prefers-reduced-motion

Для JavaScript доступен matchMedia('(prefers-reduced-motion: reduce)').matches. Если true — не запускать анимации через requestAnimationFrame, setInterval или Web Animations API. Пример: слайдер при reduceMotion не крутится автоматически, только по кнопкам. Библиотеки GSAP, Framer Motion и Anime.js поддерживают эту проверку через свои accessibility-опции.

WCAG 2.2: анимация от взаимодействия и критерий 2.3.3

WCAG 2.2 (2023) ввёл новый критерий 2.3.3 Animation from Interactions (уровень AAA): если анимация запускается от взаимодействия пользователя (клик, скролл, наведение), она должна быть отключаемой или не превышать 5 секунд. Анимация, не связанная с взаимодействием (загрузочный спиннер, progress bar), под этот критерий не попадает. Для уровня AA достаточно, чтобы анимация не была единственным способом передачи информации.

Критерий 2.3.3 был добавлен после многочисленных жалоб на motion sickness от параллакс-скроллинга и анимации «потянуть-обновить» (pull-to-refresh). W3C рекомендует всем сайтам и приложениям: не анимировать элементы более 5 секунд, предоставлять переключатель отключения анимации (через control panel или prefers-reduced-motion), не использовать пульсирующие и вспыхивающие элементы (опасно для epilepsy).

Как соблюдать WCAG 2.2 для анимации

Для соответствия WCAG 2.2 разработчику нужно: проверить prefers-reduced-motion и отключить анимацию при активной настройке, установить максимальную длительность анимации 5 секунд (если анимация не может быть отключена), предоставить UI-переключатель анимации в настройках приложения, не использовать параллакс-эффекты как единственный способ навигации и тестировать с включённым Reduce Motion во всех браузерах и на всех устройствах.

  • Проверка prefers-reduced-motion — обязательна для всех веб-сайтов с CSS/JS-анимацией
  • Максимум 5 секунд — анимация от взаимодействия не должна длиться дольше (критерий 2.3.3 AAA)
  • UI-переключатель — приложение должно иметь опцию отключения анимации в настройках
  • Нет параллакс-навигации — контент не должен быть доступен только через параллакс-скроллинг

Инструменты тестирования Reduce Motion

Для тестирования поведения приложения с Reduce Motion используйте: iOS Simulator (включить Reduce Motion в Settings > Accessibility), Android Emulator (включить «Удалить анимацию»), Chrome DevTools (Rendering > Emulate CSS media feature prefers-reduced-motion), веб-инспектор Safari (включить Reduce Motion в macOS System Preferences > Accessibility > Display). Проверяйте, что контент остаётся доступным и читаемым без анимации.

Часто задаваемые вопросы

Что такое Reduce Motion и как она работает?

Reduce Motion — accessibility-функция ОС, отключающая анимацию интерфейса (параллакс, переходы, масштабирование иконок) для людей с вестибулярными расстройствами. Включается в Settings > Accessibility. Система передаёт сигнал приложениям через UIAccessibility (iOS), Settings.Global (Android) или prefers-reduced-motion (CSS), и разработчик может адаптировать анимацию.

Как включить Reduce Motion на iPhone?

На iPhone Reduce Motion включается в Settings > Accessibility > Motion > Reduce Motion. После включения отключаются параллакс обоев, эффекты iMessage, анимация открытия приложений и переходы между экранами (заменяются на cross-fade). Системные анимации UIKit не воспроизводятся. Настройка применяется ко всем приложениям без перезагрузки устройства.

Как отключить анимацию в Android?

В Android анимация отключается двумя способами: Настройки > Специальные возможности > Удалить анимацию (рекомендуется для пользователей) или Параметры разработчика > Масштаб анимации — выключить. Accessibility-способ гарантирует, что все приложения получат сигнал. Developer Options влияют только на системные анимации и могут быть скрыты на некоторых устройствах.

Как CSS prefers-reduced-motion отключает анимацию на сайте?

CSS-медиа-функция prefers-reduced-motion: reduce позволяет отключить анимацию на уровне стилей. Рекомендуется задать универсальный сброс: animation-duration: 0.01ms, transition-duration: 0.01ms, animation-iteration-count: 1 для всех элементов. Отдельно переопределить конкретные компоненты (spinner, skeleton, parallax). JavaScript проверяется через matchMedia('(prefers-reduced-motion: reduce)').

Какие требования WCAG 2.2 к анимации?

WCAG 2.2 критерий 2.3.3 (AAA) требует, чтобы анимация от взаимодействия пользователя была отключаемой или не превышала 5 секунд. Для AA достаточно, чтобы анимация не была единственным способом передачи информации. Рекомендуется всегда проверять prefers-reduced-motion и предоставлять UI-переключатель анимации в настройках приложения.

Итоги

  • Reduce Motion — системная accessibility-функция, отключающая анимацию для предотвращения vestibular disorders и мигрени
  • iOS Reduce Motion — Settings > Accessibility > Motion; отключает параллакс, переходы и анимацию иконок
  • Android Remove Animation — Настройки > Специальные возможности; обнуляет window_animation_scale и animator_duration_scale
  • CSS prefers-reduced-motion — медиа-функция с глобальным сбросом анимации (0.01ms, iteration-count: 1)
  • WCAG 2.2 (2.3.3) — анимация от взаимодействия не более 5 секунд или отключаема (уровень AAA)
  • Проверка — UIAccessibility.isReduceMotionEnabled (iOS), Settings.Global.ANIMATOR_DURATION_SCALE (Android)
  • Тестирование — Chrome DevTools emulation, iOS Simulator, Android Emulator, веб-инспектор Safari

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также