Reduce Motion în aplicațiile mobile: esența, setările de reducere a mișcării

Autor: IT Sectr Publicat: 2026-05-16 Timp de citire: 12 min

Reduce Motion — funcția accessibility a sistemelor de operare și browserelor care dezactivează sau reduce animația interfeței pentru a preveni disconfortul utilizatorilor cu tulburări vestibulare. În iOS setarea se află în Settings > Accessibility > Motion > Reduce Motion și dezactivează paralaxa, animația tranzițiilor între ecrane și efectele pictogramelor. În Android opțiunea analogică „Șterge animația” se află în Setări > Accesibilitate. Conform datelor W3C WCAG 2.2, animația excesivă poate provoca greață, amețeli și migrenă la 15–35% dintre persoanele cu tulburări vestibulare.

Principalele puncte

  • Reduce Motion — setare accessibility care dezactivează animația interfeței pentru confortul utilizatorilor cu tulburări vestibulare
  • iOS Reduce Motion — în Settings > Accessibility > Motion: dezactivează paralaxa, tranzițiile pictogramelor și efectele mesajelor
  • Android — „Șterge animația” în Setări > Accesibilitate; dezactivează scalarea și tranzițiile
  • CSS prefers-reduced-motion — funcție media pentru dezvoltatorii web: dezactivează animația CSS la setarea de sistem
  • WCAG 2.2 — criteriul 2.3.3 prescrie dezactivarea implicită a animației de interacțiune

Ce este Reduce Motion în accessibility?

Reduce Motion — o setare de sistem care solicită sistemului de operare, browserului și aplicațiilor să minimizeze sau să dezactiveze complet animația, mișcarea, scalarea și efectele de paralaxă. Funcția este destinată persoanelor cu tulburări vestibulare, la care elementele în mișcare ale interfeței provoacă greață, amețeli, dezorientare și migrenă.

Sistemul vestibular urechii interne este responsabil pentru simțul echilibrului și orientarea în spațiu. Când ochii văd mișcare pe ecran, dar aparatul vestibular nu simte deplasarea corespunzătoare a corpului, apare un conflict senzorial. Acest conflict declanșează o reacție vegetativă: greață, transpirație rece, amețeli. Potrivit Asociației Tulburărilor Vestibulare, aproximativ 35% dintre persoanele peste 40 de ani experimentează disconfort din cauza efectelor de mișcare în interfețe.

Diferența cheie a Reduce Motion față de simpla dezactivare a animației — nivelul de sistem. Setarea activată este transmisă tuturor aplicațiilor și site-urilor web prin API-ul sistemului de operare sau funcția media CSS prefers-reduced-motion. Dezvoltatorul nu trebuie să ghicească dacă utilizatorul dorește animație — sistemul îl informează. Aceasta face parte din abordarea progressive enhancement: animația este o îmbunătățire, nu un element obligatoriu.

Ce efecte dezactivează Reduce Motion

Reduce Motion afectează efectele de paralaxă (deplasarea fundalului la înclinarea dispozitivului), animația tranzițiilor între ecrane (push, slide, fade), scalarea pictogramelor la apăsare, efectele mesajelor (bule SMS), animația de încărcare (spinner, skeleton, progress bar animation), paralaxa în jocuri și efectele de parallax scrolling web. Imaginile statice și videoclipurile nu sunt afectate.

Tipul animațieiiOS Reduce MotionAndroid Remove AnimationCSS prefers-reduced-motion
Paralaxa tapetuluiDezactiveazăDezactiveazăN/A
Tranziții între ecraneÎnlocuiește cu fadeDezactiveazăCSS transitions
Animația pictogramelorDezactiveazăNu afecteazăCSS animations
Spinner de încărcareNu afecteazăDezactiveazăCSS animations
Ecrane skeletonNu afecteazăÎnlocuiește cu staticCSS animations

Cine are nevoie de Reduce Motion

Publicul țintă principal al Reduce Motion — persoane cu tulburări vestibulare (boala Meniere, labirintită, BPPV), migrenă (în special cu aură), kinetoză (rău de mișcare în transport) și unele forme de epilepsie. Funcția este utilă și pentru utilizatorii în vârstă — modificările legate de vârstă ale aparatului vestibular cresc sensibilitatea la mișcare, precum și pentru utilizatorii cu ADHD — elementele în mișcare distrag atenția de la citire.

Reduce Motion în iOS: setare și efecte de sistem

În iOS Reduce Motion se află în Settings > Accessibility > Motion și include trei opțiuni: Reduce Motion (comutatorul principal), Auto-Play Message Effects (redarea automată a efectelor iMessage) și Auto-Play Video Previews (previzualizarea automată a videoclipurilor în App Store). Reduce Motion este cel mai puternic: dezactivează paralaxa tapetului, animația de deschidere a aplicațiilor (zoom), tranzițiile între ecrane (push este înlocuit cu cross-fade) și efectele pictogramelor pe ecranul principal.

Din punct de vedere tehnic iOS implementează Reduce Motion la nivelul UIKit prin UIView animations și UIViewControllerAnimatedTransitioning. Cu setarea activată, UIView.animate cu durata > 0 este redus la 0,01 sec, iar UIViewController.transitionDuration returnează 0. Pentru paralaxă, iOS dezactivează UIInterpolatingMotionEffect pe UIWindow. Dezvoltatorul poate verifica starea prin UIAccessibility.isReduceMotionEnabled.

Verificarea Reduce Motion în aplicația iOS

Dezvoltatorul poate adapta animația în iOS la Reduce Motion: înlocui tranzițiile complexe cu efecte fade, dezactiva paralaxa în componentele UI personalizate și scurta durata animațiilor. SwiftUI oferă un modificator special .animation(nil) când reduceMotion este activ.

swift
import UIKit

class MotionManager {

    // Verificarea stării Reduce Motion
    static var isReduceMotionEnabled: Bool {
        return UIAccessibility.isReduceMotionEnabled
    }

    // Animație sigură ținând cont de 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 — modificator pentru 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 }
    }
}

// Abonare la modificarea Reduce Motion
NotificationCenter.default.addObserver(
    self,
    selector: #selector(motionStatusChanged),
    name: UIAccessibility.reduceMotionStatusDidChangeNotification,
    object: nil
)

Clasa MotionManager verifică isReduceMotionEnabled și adaptează durata animației: cu Reduce Motion activ, durata este redusă la 0,01 sec (practic instantaneu). Modificatorul SwiftUI .animation(nil) dezactivează complet animația când reduceMotion == true. Abonarea la reduceMotionStatusDidChangeNotification permite comutarea dinamică a animației fără reîncărcarea aplicației.

Auto-Play Message Effects în iMessage

O opțiune separată iOS — Auto-Play Message Effects — controlează redarea efectelor în iMessage: animația baloanelor, confetti, lasere și artificii. Cu Reduce Motion activ, efectele iMessage sunt dezactivate automat. Dezvoltatorul poate verifica această opțiune prin UIAccessibility.isReduceMotionEnabled — nu există un API separat pentru Message Effects, acestea sunt legate de setarea generală.

Șterge animația în Android: Developer Options și Accessibility

În Android setarea „Șterge animația” se află în două locuri: Setări > Accesibilitate > Șterge animația (pentru setările de accesibilitate) și Opțiuni dezvoltator > Scara animației (pentru dezvoltatori). Versiunea de accesibilitate dezactivează toate animațiile de sistem, inclusiv tranzițiile între ecrane, animația de deschidere a aplicațiilor și efectele de încărcare. Opțiunile dezvoltator permit reducerea scării la 0,5x, 0,1x sau dezactivarea completă.

Din punct de vedere tehnic Android implementează dezactivarea animației prin proprietăți de sistem: window_animation_scale, transition_animation_scale și animator_duration_scale. La setarea de accesibilitate, toate trei primesc valoarea 0. Lansatorul de sistem și aplicațiile de sistem verifică aceste valori. Pentru aplicațiile terțe, Android recomandă utilizarea Jetpack Compose și View system, care citesc automat setarea de sistem prin AnimationScaleObserver.

Verificarea în aplicația Android

Dezvoltatorul poate verifica starea animației în Android prin Settings.Global și adapta UI. Jetpack Compose oferă AnimationScaleObserver pentru adaptarea automată. Valoarea cheie — animator_duration_scale: dacă este 0, animația este complet dezactivată.

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 {

    // Verificarea dezactivării animației
    fun isAnimationDisabled(context: Context): Boolean {
        return try {
            Settings.Global.getFloat(
                context.contentResolver,
                Settings.Global.ANIMATOR_DURATION_SCALE
            ) == 0f
        } catch (e: Settings.SettingNotFoundException) {
            false
        }
    }

    // Observarea modificării animației (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 — animație ținând cont de setări
@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"
    )
    // Interfață cu animație
}

Clasa AndroidMotionHelper verifică ANIMATOR_DURATION_SCALE prin Settings.Global, oferă ContentObserver pentru urmărirea modificărilor și permite animațiilor Jetpack Compose să se adapteze: cu animația dezactivată, durationMillis = 0 (aplicare instantanee). Pentru sistemul View, utilizați ViewPropertyAnimator.withLayer() și verificați isAnimationDisabled() înainte de a porni animația.

Diferența între Accessibility și Developer Options

Setarea de accesibilitate „Șterge animația” în Android — singura modalitate pentru utilizatorul obișnuit de a dezactiva animația. Opțiunile dezvoltator sunt destinate exclusiv dezvoltatorilor și pot fi ascunse. Setarea de accesibilitate este garantată a fi transmisă tuturor aplicațiilor prin API-ul de sistem. Dezvoltatorul ar trebui să se orienteze după AccessibilityManager, nu după Opțiunile dezvoltator.

CSS prefers-reduced-motion: funcția media pentru web

Funcția media CSS prefers-reduced-motion permite dezvoltatorilor web să dezactiveze sau să înlocuiască animația atunci când utilizatorul a activat Reduce Motion în sistemul de operare. Browserul transmite valoarea reduce la setarea de sistem activă, no-preference — dacă setarea nu a fost modificată. Este suportată de toate browserele moderne din 2020: Chrome 74+, Safari 10.3+, Firefox 64+, Edge 79+.

Recomandarea MDN și W3C — setați întotdeauna prefers-reduced-motion: reduce împreună cu animațiile. Utilizatorul care a activat Reduce Motion nu ar trebui să vadă pulsații, paralaxă, redarea automată a caruselurilor și încărcarea skeleton. În locul animației se poate afișa conținut static sau se poate utiliza CSS transition cu durată minimă. Mai jos este un exemplu de adaptare completă.

Adaptarea paginii web prin prefers-reduced-motion

La prefers-reduced-motion: reduce pagina web trebuie să: dezactiveze animațiile CSS (@keyframes), înlocuiască CSS transitions cu modificări instantanee, oprească animațiile JavaScript (requestAnimationFrame), dezactiveze parallax scrolling, oprească caruselurile și glisorele, dezactiveze efectele skeleton și înlocuiască spinner-ul cu un indicator static.

css
/* Animații de bază (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: dezactivăm totul */
@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; }
}

În exemplul CSS se utilizează o resetare globală a animației la prefers-reduced-motion: reduce: toate animațiile și tranzițiile primesc duration 0.01ms și iteration-count 1. Au fost redefinite separat spinner (border static), skeleton (fundal gri fără pâlpâire), paralaxa (dezactivată) și carusel (scroll-behavior: auto în loc de smooth). Selectorul universal * — protecție pentru toate elementele.

Detectarea prefers-reduced-motion în JavaScript

Pentru JavaScript este disponibil matchMedia('(prefers-reduced-motion: reduce)').matches. Dacă este true — nu rula animații prin requestAnimationFrame, setInterval sau Web Animations API. Exemplu: glisorul cu reduceMotion nu se rotește automat, ci doar prin butoane. Bibliotecile GSAP, Framer Motion și Anime.js suportă această verificare prin opțiunile lor de accesibilitate.

WCAG 2.2: animația de interacțiune și criteriul 2.3.3

WCAG 2.2 (2023) a introdus criteriul nou 2.3.3 Animation from Interactions (nivel AAA): dacă animația este declanșată de interacțiunea utilizatorului (clic, derulare, hover), aceasta trebuie să poată fi dezactivată sau să nu depășească 5 secunde. Animația necorelată cu interacțiunea (spinner de încărcare, progress bar) nu intră sub acest criteriu. Pentru nivelul AA este suficient ca animația să nu fie singurul mod de transmitere a informației.

Criteriul 2.3.3 a fost adăugat după numeroase plângeri privind răul de mișcare cauzat de parallax scrolling și animația „trageți-reîmprospătați”. W3C recomandă tuturor site-urilor și aplicațiilor: nu animați elementele mai mult de 5 secunde, oferiți un comutator de dezactivare a animației (prin panoul de control sau prefers-reduced-motion), nu utilizați elemente pulsatorii și intermitente (periculoase pentru epilepsie).

Cum să respectați WCAG 2.2 pentru animație

Pentru conformitatea cu WCAG 2.2 dezvoltatorul trebuie să: verifice prefers-reduced-motion și dezactiveze animația la setarea activă, stabilească durata maximă a animației la 5 secunde (dacă animația nu poate fi dezactivată), ofere un comutator UI al animației în setările aplicației, nu utilizeze efectele de paralaxă ca unic mod de navigare și testeze cu Reduce Motion activat în toate browserele și pe toate dispozitivele.

  • Verificarea prefers-reduced-motion — obligatorie pentru toate site-urile cu animație CSS/JS
  • Maximum 5 secunde — animația de interacțiune nu trebuie să dureze mai mult (criteriul 2.3.3 AAA)
  • Comutator UI — aplicația trebuie să aibă o opțiune de dezactivare a animației în setări
  • Fără navigare prin paralaxă — conținutul nu trebuie să fie accesibil doar prin parallax scrolling

Instrumente de testare Reduce Motion

Pentru testarea comportamentului aplicației cu Reduce Motion utilizați: iOS Simulator (activați Reduce Motion în Settings > Accessibility), Android Emulator (activați „Șterge animația”), Chrome DevTools (Rendering > Emulate CSS media feature prefers-reduced-motion), inspectorul web Safari (activați Reduce Motion în macOS System Preferences > Accessibility > Display). Verificați că conținutul rămâne accesibil și lizibil fără animație.

Întrebări frecvente

Ce este Reduce Motion și cum funcționează?

Reduce Motion — funcția accessibility a sistemului de operare care dezactivează animația interfeței (paralaxă, tranziții, scalare pictograme) pentru persoanele cu tulburări vestibulare. Se activează în Settings > Accessibility. Sistemul transmite semnalul aplicațiilor prin UIAccessibility (iOS), Settings.Global (Android) sau prefers-reduced-motion (CSS), iar dezvoltatorul poate adapta animația.

Cum se activează Reduce Motion pe iPhone?

Pe iPhone Reduce Motion se activează în Settings > Accessibility > Motion > Reduce Motion. După activare, sunt dezactivate: paralaxa tapetului, efectele iMessage, animația de deschidere a aplicațiilor și tranzițiile între ecrane (înlocuite cu cross-fade). Animațiile de sistem UIKit nu sunt redate. Setarea se aplică tuturor aplicațiilor fără a reporni dispozitivul.

Cum se dezactivează animația în Android?

În Android animația se dezactivează în două moduri: Setări > Accesibilitate > Șterge animația (recomandat pentru utilizatori) sau Opțiuni dezvoltator > Scara animației — dezactivați. Metoda de accesibilitate garantează că toate aplicațiile primesc semnalul. Opțiunile dezvoltator afectează doar animațiile de sistem și pot fi ascunse pe unele dispozitive.

Cum dezactivează CSS prefers-reduced-motion animația pe site?

Funcția media CSS prefers-reduced-motion: reduce permite dezactivarea animației la nivelul stilurilor. Se recomandă setarea unei resetări universale: animation-duration: 0.01ms, transition-duration: 0.01ms, animation-iteration-count: 1 pentru toate elementele. Redefiniți separat componentele specifice (spinner, skeleton, paralaxă). JavaScript se verifică prin matchMedia('(prefers-reduced-motion: reduce)').

Care sunt cerințele WCAG 2.2 pentru animație?

WCAG 2.2 criteriul 2.3.3 (AAA) cere ca animația declanșată de interacțiunea utilizatorului să poată fi dezactivată sau să nu depășească 5 secunde. Pentru AA este suficient ca animația să nu fie singurul mod de transmitere a informației. Se recomandă verificarea întotdeauna a prefers-reduced-motion și oferirea unui comutator UI al animației în setările aplicației.

Concluzii

  • Reduce Motion — funcția accessibility de sistem care dezactivează animația pentru prevenirea tulburărilor vestibulare și a migrenei
  • iOS Reduce Motion — Settings > Accessibility > Motion; dezactivează paralaxa, tranzițiile și animația pictogramelor
  • Android Remove Animation — Setări > Accesibilitate; resetează window_animation_scale și animator_duration_scale
  • CSS prefers-reduced-motion — funcție media cu resetare globală a animației (0.01ms, iteration-count: 1)
  • WCAG 2.2 (2.3.3) — animația de interacțiune nu mai mult de 5 secunde sau dezactivabilă (nivel AAA)
  • Verificare — UIAccessibility.isReduceMotionEnabled (iOS), Settings.Global.ANIMATOR_DURATION_SCALE (Android)
  • Testare — emulare Chrome DevTools, iOS Simulator, Android Emulator, inspector web Safari

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și