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 Motion Android Remove Animation CSS prefers-reduced-motion
Паралакс шпалер Вимикає Вимикає N/A
Переходи між екранами Замінює на fade Вимикає CSS transitions
Анімація іконок Вимикає Не впливає CSS animations
Spinner завантаження Не впливає Вимикає CSS animations
Skeleton screens Не впливає Замінює на static CSS 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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