Reduce Motion em aplicativos móveis: o que é e configurações de redução de movimento

Autor: IT Sectr Publicado: 2026-05-16 Tempo de leitura: 12 min

Reduce Motion — um recurso de acessibilidade de sistemas operacionais e navegadores que desativa ou reduz a animação da interface para evitar desconforto em usuários com distúrbios vestibulares. No iOS, a configuração fica em Settings > Accessibility > Motion > Reduce Motion e desativa o parallax, as animações de transição entre telas e os efeitos de ícones. No Android, a opção equivalente “Remover animações” fica em Settings > Accessibility. Segundo W3C WCAG 2.2, a animação excessiva pode causar náuseas, tonturas e enxaquecas em 15–35% das pessoas com distúrbios vestibulares.

Principais pontos

  • Reduce Motion — uma configuração de acessibilidade que desativa a animação da interface para o conforto de usuários com distúrbios vestibulares
  • iOS Reduce Motion — em Settings > Accessibility > Motion: desativa parallax, transições de ícones e efeitos de mensagens
  • Android — “Remover animações” em Settings > Accessibility; desativa dimensionamento e transições
  • CSS prefers-reduced-motion — uma media feature para desenvolvedores web: desativa a animação CSS quando a configuração do sistema está ativa
  • WCAG 2.2 — o critério 2.3.3 exige desativar a animação por interação por padrão

O que é Reduce Motion em acessibilidade?

Reduce Motion — uma configuração do sistema que instrui o sistema operacional, o navegador e os aplicativos a minimizar ou desativar completamente animação, movimento, dimensionamento e efeitos de parallax. O recurso é destinado a pessoas com distúrbios vestibulares, em quem os elementos em movimento da interface causam náuseas, tonturas, desorientação e enxaquecas.

O sistema vestibular do ouvido interno é responsável pelo sentido de equilíbrio e orientação espacial. Quando os olhos veem movimento na tela, mas o aparelho vestibular não percebe o deslocamento correspondente do corpo, ocorre um conflito sensorial. Esse conflito desencadeia uma reação vegetativa: náuseas, suor frio, tonturas. Segundo a Vestibular Disorders Association, cerca de 35% das pessoas com mais de 40 anos sentem desconforto com efeitos de movimento nas interfaces.

A diferença fundamental entre Reduce Motion e simplesmente desativar a animação é o nível do sistema. Quando ativada, a configuração é transmitida a todos os aplicativos e sites por meio da API do sistema operacional ou da media feature CSS prefers-reduced-motion. O desenvolvedor não precisa adivinhar se o usuário quer animação — o sistema operacional informa. Isso faz parte da abordagem de progressive enhancement: a animação é um aprimoramento, não um elemento obrigatório.

Quais efeitos o Reduce Motion desativa

Reduce Motion afeta efeitos de parallax (deslocamento do fundo ao inclinar o dispositivo), animações de transição entre telas (push, slide, fade), dimensionamento de ícones ao tocar, efeitos de mensagens (balões SMS), animações de carregamento (spinner, skeleton, animação de barra de progresso), parallax em jogos e efeitos web de parallax scrolling. Imagens estáticas e vídeos não são afetados.

Tipo de animação iOS Reduce Motion Android Remove Animation CSS prefers-reduced-motion
Parallax do papel de parede Desativa Desativa N/A
Transições entre telas Substitui por fade Desativa CSS transitions
Animação de ícones Desativa Sem efeito CSS animations
Spinner de carregamento Sem efeito Desativa CSS animations
Telas skeleton Sem efeito Substitui por estático CSS animations

Quem precisa de Reduce Motion

O público principal do Reduce Motion são pessoas com distúrbios vestibulares (doença de Ménière, labirintite, VPPB), enxaqueca (especialmente com aura), cinetose (enjoo de movimento no transporte) e certas formas de epilepsia. O recurso também é útil para usuários idosos — mudanças relacionadas à idade no aparelho vestibular aumentam a sensibilidade ao movimento — e para usuários com TDAH, pois os elementos em movimento distraem a leitura.

Reduce Motion no iOS: configuração e efeitos do sistema

No iOS, o Reduce Motion fica em Settings > Accessibility > Motion e inclui três opções: Reduce Motion (o interruptor principal), Auto-Play Message Effects (reprodução automática de efeitos do iMessage) e Auto-Play Video Previews (reprodução automática de vídeos na App Store). O Reduce Motion é o mais poderoso: desativa o parallax do papel de parede, a animação de abertura de aplicativos (zoom), as transições entre telas (push é substituído por cross-fade) e os efeitos de ícones na tela inicial.

Tecnicamente, o iOS implementa o Reduce Motion no nível do UIKit por meio de UIView animations e UIViewControllerAnimatedTransitioning. Com a configuração ativada, UIView.animate com duração > 0 é reduzido para 0,01 segundos, e UIViewController.transitionDuration retorna 0. Para o parallax, o iOS desativa UIInterpolatingMotionEffect no UIWindow. O desenvolvedor pode verificar o estado por meio de UIAccessibility.isReduceMotionEnabled.

Verificar Reduce Motion em um aplicativo iOS

Um desenvolvedor pode adaptar a animação no iOS ao Reduce Motion: substituir transições complexas por efeitos fade, desativar o parallax em componentes de UI personalizados e encurtar as durações das animações. O SwiftUI fornece um modificador especial .animation(nil) quando o reduceMotion está ativo.

swift
import UIKit

class MotionManager {

    // Verificar o estado de Reduce Motion
    static var isReduceMotionEnabled: Bool {
        return UIAccessibility.isReduceMotionEnabled
    }

    // Animação segura que respeita 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 — modificador para 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 }
    }
}

// Assinatura da mudança de Reduce Motion
NotificationCenter.default.addObserver(
    self,
    selector: #selector(motionStatusChanged),
    name: UIAccessibility.reduceMotionStatusDidChangeNotification,
    object: nil
)

A classe MotionManager verifica isReduceMotionEnabled e adapta a duração da animação: quando o Reduce Motion está ativo, a duração é reduzida para 0,01 segundos (praticamente instantânea). O modificador .animation(nil) do SwiftUI desativa completamente a animação quando reduceMotion == true. Assinar reduceMotionStatusDidChangeNotification permite alternar dinamicamente a animação sem reiniciar o aplicativo.

Auto-Play Message Effects no iMessage

Uma opção separada do iOS — Auto-Play Message Effects — controla a reprodução de efeitos no iMessage: animação de balões, confete, lasers e fogos de artifício. Quando o Reduce Motion está ativado, os efeitos do iMessage são desativados automaticamente. Um desenvolvedor pode verificar essa opção por meio de UIAccessibility.isReduceMotionEnabled — não há API separada para Message Effects; eles estão vinculados à configuração geral.

Remover animações no Android: Opções de desenvolvedor e Acessibilidade

No Android, a configuração “Remover animações” fica em dois lugares: Settings > Accessibility > Remover animações (para configurações de acessibilidade) e Opções do desenvolvedor > Escala de animação (para desenvolvedores). A versão de acessibilidade desativa todas as animações do sistema, incluindo transições entre telas, animação de abertura de aplicativos e efeitos de carregamento. As Opções do desenvolvedor permitem reduzir a escala para 0,5x, 0,1x ou desativá-la completamente.

Tecnicamente, o Android implementa a desativação de animações por meio de propriedades do sistema: window_animation_scale, transition_animation_scale e animator_duration_scale. Com a configuração de acessibilidade, as três são definidas como 0. O Launcher do sistema e os aplicativos do sistema verificam esses valores. Para aplicativos de terceiros, o Android recomenda usar Jetpack Compose e o sistema View, que leem automaticamente a configuração do sistema por meio do AnimationScaleObserver.

Verificação em um aplicativo Android

Um desenvolvedor pode verificar o estado da animação no Android por meio de Settings.Global e adaptar a UI. O Jetpack Compose fornece AnimationScaleObserver para ajuste automático. O valor-chave é animator_duration_scale: se for 0, a animação está totalmente desativada.

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 {

    // Verificar se a animação está desativada
    fun isAnimationDisabled(context: Context): Boolean {
        return try {
            Settings.Global.getFloat(
                context.contentResolver,
                Settings.Global.ANIMATOR_DURATION_SCALE
            ) == 0f
        } catch (e: Settings.SettingNotFoundException) {
            false
        }
    }

    // Observar a mudança de animação (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ção que respeita as configurações
@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 com animação
}

A classe AndroidMotionHelper verifica ANIMATOR_DURATION_SCALE por meio de Settings.Global, fornece um ContentObserver para rastrear mudanças e permite que as animações do Jetpack Compose se adaptem: quando a animação está desativada, durationMillis = 0 (aplicação instantânea). Para o sistema View, use ViewPropertyAnimator.withLayer() e verifique isAnimationDisabled() antes de iniciar uma animação.

Diferença entre Acessibilidade e Opções do desenvolvedor

A configuração de acessibilidade “Remover animações” no Android é a única maneira de um usuário comum desativar a animação. As Opções do desenvolvedor são destinadas apenas a desenvolvedores e podem estar ocultas. A configuração de acessibilidade é garantidamente transmitida a todos os aplicativos por meio da API do sistema. O desenvolvedor deve confiar no AccessibilityManager e não nas Opções do desenvolvedor.

CSS prefers-reduced-motion: uma media feature para a web

A media feature CSS prefers-reduced-motion permite que desenvolvedores web desativem ou substituam a animação quando o usuário ativou Reduce Motion no sistema operacional. O navegador informa o valor reduce quando a configuração do sistema está ativa e no-preference quando não foi alterada. É suportada por todos os navegadores modernos desde 2020: Chrome 74+, Safari 10.3+, Firefox 64+, Edge 79+.

A recomendação de MDN e W3C — sempre definir prefers-reduced-motion: reduce junto com as animações. Um usuário que ativou Reduce Motion não deve ver pulsações, parallax, carrosséis de reprodução automática ou carregamento skeleton. Em vez de animação, pode-se mostrar conteúdo estático ou usar uma transição CSS com duração mínima. Abaixo está um exemplo de adaptação completa.

Adaptação de uma página web por meio de prefers-reduced-motion

Com prefers-reduced-motion: reduce, uma página web deve: desativar animações CSS (@keyframes), substituir transições CSS por mudanças instantâneas, parar animações JavaScript (requestAnimationFrame), desativar parallax scrolling, parar carrosséis e sliders, desativar efeitos skeleton e substituir o spinner por um indicador estático.

css
/* Animações básicas (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: desativando tudo */
@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; }
}

No exemplo de CSS, usa-se um reset global de animação para prefers-reduced-motion: reduce: todas as animações e transições recebem duração 0,01ms e iteration-count 1. Separadamente, são sobrescritos o spinner (borda estática), o skeleton (fundo cinza sem oscilação), o parallax (desativado) e o carrossel (scroll-behavior: auto em vez de smooth). O seletor universal * é uma rede de segurança para todos os elementos.

Detecção de prefers-reduced-motion em JavaScript

Para JavaScript, está disponível matchMedia('(prefers-reduced-motion: reduce)').matches. Se for true — não execute animações por meio de requestAnimationFrame, setInterval ou da Web Animations API. Exemplo: um slider com reduceMotion não gira automaticamente, apenas pelos botões. Bibliotecas como GSAP, Framer Motion e Anime.js suportam essa verificação por meio de suas opções de acessibilidade.

WCAG 2.2: animação por interação e critério 2.3.3

O WCAG 2.2 (2023) introduziu um novo critério 2.3.3 Animation from Interactions (nível AAA): se a animação é acionada pela interação do usuário (clique, rolagem, hover), ela deve poder ser desativada ou não exceder 5 segundos. A animação não relacionada à interação (spinner de carregamento, barra de progresso) não se enquadra nesse critério. Para o nível AA, basta que a animação não seja a única forma de transmitir informação.

O critério 2.3.3 foi adicionado após inúmeras queixas de motion sickness causado por parallax scrolling e animação “pull-to-refresh”. O W3C recomenda a todos os sites e aplicativos: não animar elementos por mais de 5 segundos, fornecer um interruptor para desativar a animação (por meio de um painel de controle ou prefers-reduced-motion) e não usar elementos pulsantes e intermitentes (perigoso para epilepsia).

Como cumprir o WCAG 2.2 para animação

Para cumprir o WCAG 2.2, um desenvolvedor precisa: verificar prefers-reduced-motion e desativar a animação quando a configuração estiver ativa, definir uma duração máxima de animação de 5 segundos (se a animação não puder ser desativada), fornecer um interruptor de UI para animação nas configurações do aplicativo, não usar efeitos de parallax como única forma de navegação e testar com Reduce Motion ativado em todos os navegadores e dispositivos.

  • Verificação de prefers-reduced-motion — obrigatória para todos os sites com animação CSS/JS
  • Máximo de 5 segundos — a animação por interação não deve durar mais (critério 2.3.3 AAA)
  • Interruptor de UI — o aplicativo deve ter uma opção de desativar a animação nas configurações
  • Sem navegação por parallax — o conteúdo não deve ser acessível apenas por parallax scrolling

Ferramentas para testar Reduce Motion

Para testar o comportamento do aplicativo com Reduce Motion, use: iOS Simulator (ativar Reduce Motion em Settings > Accessibility), Android Emulator (ativar “Remover animações”), Chrome DevTools (Rendering > Emulate CSS media feature prefers-reduced-motion) e o inspetor web do Safari (ativar Reduce Motion em macOS System Preferences > Accessibility > Display). Verifique se o conteúdo permanece acessível e legível sem animação.

Perguntas frequentes

O que é Reduce Motion e como funciona?

Reduce Motion — um recurso de acessibilidade do sistema operacional que desativa a animação da interface (parallax, transições, dimensionamento de ícones) para pessoas com distúrbios vestibulares. É ativado em Settings > Accessibility. O sistema transmite o sinal aos aplicativos por meio de UIAccessibility (iOS), Settings.Global (Android) ou prefers-reduced-motion (CSS), e o desenvolvedor pode adaptar a animação.

Como ativar Reduce Motion em um iPhone?

Em um iPhone, o Reduce Motion é ativado em Settings > Accessibility > Motion > Reduce Motion. Após a ativação, são desativados o parallax do papel de parede, os efeitos do iMessage, a animação de abertura de aplicativos e as transições entre telas (substituídas por cross-fade). As animações do sistema UIKit não são reproduzidas. A configuração se aplica a todos os aplicativos sem reiniciar o dispositivo.

Como desativar a animação no Android?

No Android, a animação é desativada de duas formas: Settings > Accessibility > Remover animações (recomendado para usuários) ou Opções do desenvolvedor > Escala de animação — desativar. O método de acessibilidade garante que todos os aplicativos recebam o sinal. As Opções do desenvolvedor afetam apenas as animações do sistema e podem estar ocultas em alguns dispositivos.

Como o CSS prefers-reduced-motion desativa a animação em um site?

A media feature CSS prefers-reduced-motion: reduce permite desativar a animação no nível dos estilos. Recomenda-se definir um reset universal: animation-duration: 0,01ms, transition-duration: 0,01ms, animation-iteration-count: 1 para todos os elementos. Sobrescreva separadamente os componentes específicos (spinner, skeleton, parallax). O JavaScript é verificado por meio de matchMedia('(prefers-reduced-motion: reduce)').

Quais são os requisitos do WCAG 2.2 para animação?

WCAG 2.2 o critério 2.3.3 (AAA) exige que a animação acionada pela interação do usuário seja desativável ou não exceda 5 segundos. Para AA, basta que a animação não seja a única forma de transmitir informação. Recomenda-se sempre verificar prefers-reduced-motion e fornecer um interruptor de UI para animação nas configurações do aplicativo.

Resumo

  • Reduce Motion — um recurso de acessibilidade do sistema que desativa a animação para prevenir distúrbios vestibulares e enxaqueca
  • iOS Reduce Motion — Settings > Accessibility > Motion; desativa parallax, transições e animação de ícones
  • Android Remove Animation — Settings > Accessibility; zera window_animation_scale e animator_duration_scale
  • CSS prefers-reduced-motion — uma media feature com reset global de animação (0,01ms, iteration-count: 1)
  • WCAG 2.2 (2.3.3) — animação por interação não excede 5 segundos ou é desativável (nível AAA)
  • Verificação — UIAccessibility.isReduceMotionEnabled (iOS), Settings.Global.ANIMATOR_DURATION_SCALE (Android)
  • Testes — emulação no Chrome DevTools, iOS Simulator, Android Emulator, inspetor web do Safari

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também