Reduce Motion в мобилните приложения: същност, настройки за намаляване на движението

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

Reduce Motion — accessibility функция на операционните системи и браузърите, която изключва или намалява анимацията на интерфейса за предотвратяване на дискомфорт при потребители с вестибуларни нарушения. В iOS настройката се намира в Settings > Accessibility > Motion > Reduce Motion и изключва паралакс, анимация на преходи между екрани и ефекти на икони. В Android аналогичната опция „Премахване на анимация” се намира в Настройки > Достъпност. Според данни на W3C WCAG 2.2, прекомерната анимация може да предизвика гадене, замайване и мигрена при 15–35% от хората с вестибуларни нарушения.

Основни точки

  • Reduce Motion — accessibility настройка, която изключва анимацията на интерфейса за комфорт на потребители с вестибуларни нарушения
  • iOS Reduce Motion — в Settings > Accessibility > Motion: изключва паралакс, преходи на икони и ефекти на съобщения
  • Android — „Премахване на анимация” в Настройки > Достъпност; изключва мащабиране и преходи
  • CSS prefers-reduced-motion — медийна функция за уеб разработчици: изключва CSS анимация при системна настройка
  • WCAG 2.2 — критерий 2.3.3 предписва изключване на анимация от взаимодействие по подразбиране

Какво е Reduce Motion в accessibility?

Reduce Motion — системна настройка, която нарежда на операционната система, браузъра и приложенията да минимизират или напълно да изключат анимация, движение, мащабиране и паралакс ефекти. Функцията е предназначена за хора с вестибуларни нарушения, при които движещите се елементи на интерфейса причиняват гадене, замайване, дезориентация и мигрена.

Вестибуларната система на вътрешното ухо отговаря за чувството за равновесие и ориентация в пространството. Когато очите виждат движение на екрана, а вестибуларният апарат не усеща съответното движение на тялото, възниква сензорен конфликт. Този конфликт задейства вегетативна реакция: гадене, студена пот, замайване. Според данни на Асоциацията за вестибуларни нарушения, около 35% от хората над 40 години изпитват дискомфорт от ефектите на движение в интерфейсите.

Ключовата разлика на 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
Паралакс на тапетИзключваИзключваН/П
Преходи между екраниЗаменя с fadeИзключваCSS transitions
Анимация на икониИзключваНе влияеCSS animations
Spinner на зарежданеНе влияеИзключваCSS animations
Скелетни екраниНе влияеЗаменя с staticCSS animations

Кой има нужда от Reduce Motion

Основната целева аудитория на Reduce Motion — хора с вестибуларни нарушения (болест на Мениер, лабиринтит, BPPV), мигрена (особено с аура), кинетоза (прилошаване при пътуване) и някои форми на епилепсия. Функцията е полезна и за възрастни потребители — свързаните с възрастта промени във вестибуларния апарат повишават чувствителността към движение, както и за потребители с ADHD — движещите се елементи разсейват от четене.

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: анимация на балони, конфети, лазери и фойерверки. Когато Reduce Motion е включен, iMessage ефектите се изключват автоматично. Разработчикът може да провери тази опция чрез UIAccessibility.isReduceMotionEnabled — няма отделен API за Message Effects, те са свързани с общата настройка.

Премахване на анимация в Android: Developer Options и Accessibility

В Android настройката „Премахване на анимация” се намира на две места: Настройки > Достъпност > Премахване на анимация (за accessibility настройки) и Опции за разработчици > Мащаб на анимация (за разработчици). Версията за достъпност изключва всички системни анимации, включително преходи между екрани, анимация на отваряне на приложения и ефекти на зареждане. Опциите за разработчици позволяват намаляване на мащаба до 0,5x, 0,1x или пълно изключване.

Технически Android реализира изключване на анимация чрез системни свойства: 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 — единственият начин за обикновен потребител да изключи анимация. Опциите за разработчици са предназначени само за разработчици и могат да бъдат скрити. Accessibility настройката гарантирано се предава на всички приложения чрез системния API. Разработчикът трябва да се ориентира по AccessibilityManager, а не по Опциите за разработчици.

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, не трябва да вижда пулсации, паралакс, автоматично възпроизвеждане на карусели и скелетно зареждане. Вместо анимация може да се показва статично съдържание или да се използва CSS transition с минимална продължителност. По-долу е даден пример за пълна адаптация.

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

При prefers-reduced-motion: reduce уеб страницата трябва да: изключи CSS анимации (@keyframes), замени CSS transitions с моментни промени, спре JavaScript анимации (requestAnimationFrame), изключи parallax scrolling, спре карусели и плъзгачи, изключи скелетни ефекти и замени 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 (сив фон без трептене), паралакс (изключен) и карусел (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 поддържат тази проверка чрез своите опции за достъпност.

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

WCAG 2.2 (2023) въведе нов критерий 2.3.3 Animation from Interactions (ниво AAA): ако анимацията се задейства от взаимодействие на потребителя (клик, превъртане, задържане), тя трябва да може да бъде изключена или да не надвишава 5 секунди. Анимацията, която не е свързана с взаимодействие (spinner на зареждане, лента за напредък), не попада под този критерий. За ниво AA е достатъчно анимацията да не е единственият начин за предаване на информация.

Критерий 2.3.3 беше добавен след множество оплаквания от прилошаване поради parallax scrolling и анимация „дръпни-обнови”. W3C препоръчва на всички сайтове и приложения: не анимирайте елементи повече от 5 секунди, предоставете превключвател за изключване на анимация (чрез контролен панел или prefers-reduced-motion), не използвайте пулсиращи и мигащи елементи (опасно за епилепсия).

Как да спазваме WCAG 2.2 за анимация

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

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

Инструменти за тестване на 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 анимацията се изключва по два начина: Настройки > Достъпност > Премахване на анимация (препоръчва се за потребители) или Опции за разработчици > Мащаб на анимация — изключете. Начинът за достъпност гарантира, че всички приложения получават сигнала. Опциите за разработчици засягат само системни анимации и могат да бъдат скрити на някои устройства.

Как CSS prefers-reduced-motion изключва анимация на уебсайт?

CSS медийната функция prefers-reduced-motion: reduce позволява изключване на анимация на ниво стилове. Препоръчва се задаване на универсално нулиране: animation-duration: 0.01ms, transition-duration: 0.01ms, animation-iteration-count: 1 за всички елементи. Отделно предефинирайте конкретни компоненти (spinner, skeleton, паралакс). 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 функция, която изключва анимация за предотвратяване на вестибуларни нарушения и мигрена
  • 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, iOS Simulator, Android Emulator, уеб инспектор на Safari

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

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също