Programação Por Equipe DevBras

Capa do artigo: Animação de interface que explica a tela e some quando a pessoa pede menos movimento

Animação de interface que explica a tela e some quando a pessoa pede menos movimento

Anime só o que mostra de onde algo veio, mantenha transições curtas e troque deslizamento por aparição direta quando o sistema pede menos movimento.

O Mercadinho Bom Preço ganhou um site novo: o carrinho desliza da direita com um leve quique, o banner gira sem parar, os cartões de produto sobem ao entrar na tela e o botão de compra pulsa. Na reunião, todo mundo achou moderno. Na primeira semana, chegaram dois e-mails de clientes dizendo que sentiam enjoo ao rolar a página, e o tempo médio até o primeiro clique em "Comprar" aumentou.

A resposta curta: animação boa responde a uma ação e explica uma mudança — de onde o painel veio, para onde o item foi. Ela é curta, não se repete sozinha e nada de conteúdo depende dela. E quando a pessoa ativa "reduzir movimento" no sistema, a página troca deslizamento e zoom por aparição direta ou um esmaecimento simples, usando a media query prefers-reduced-motion.

Por que movimento demais atrapalha

O olho humano é atraído por movimento antes de qualquer outra coisa. Isso é útil quando o movimento indica algo relevante: "o item entrou no carrinho, que está aqui". É prejudicial quando o movimento não diz nada, porque ele rouba a atenção do que a pessoa estava tentando ler. Um banner que gira a cada três segundos compete com a lista de preços o tempo inteiro.

Para uma parte das pessoas, o problema não é distração: é mal-estar físico. Quem tem distúrbios vestibulares pode sentir tontura e náusea com efeitos de paralaxe, zoom e deslizamentos grandes. Por isso os sistemas operacionais têm uma opção de reduzir movimento, e os navegadores expõem essa escolha ao CSS e ao JavaScript.

As diretrizes WCAG tratam do tema em dois critérios: o 2.2.2 (Pausar, Parar, Ocultar) pede um jeito de pausar conteúdo que se move sozinho por mais de cinco segundos junto de outro conteúdo, e o 2.3.3 (Animação a partir de Interações) pede que a animação disparada por interação possa ser desligada, salvo quando essencial. Se o seu problema é especificamente animação contínua, como carrossel e fundo animado, há um guia vizinho: animação contínua respeita quem pediu menos movimento. Este aqui trata das transições da interface.

Como decidir o que animar

  1. Liste cada movimento da tela e escreva, em uma frase, o que ele comunica.
  2. Corte o que não comunica nada. No Bom Preço, o botão pulsando e os cartões subindo saíram.
  3. Mantenha o que explica uma mudança de estado: o carrinho abrindo do lado onde fica o ícone, o item confirmado.
  4. Encurte. Transições de interface costumam funcionar bem na faixa de 150 a 300 ms. Mais que isso, a pessoa espera a animação acabar para continuar.
  5. Ofereça pausa para tudo que se move sozinho.
  6. Escreva a versão sem movimento primeiro e acrescente a animação só para quem não pediu menos.
  7. Teste com a preferência ligada.

CSS: movimento só para quem não pediu menos

Em vez de animar tudo e depois desligar, comece pela versão parada e acrescente movimento dentro de no-preference. Assim, navegadores e casos não previstos ficam no lado seguro.

.carrinho {
  position: fixed;
  inset: 0 0 0 auto;
  width: min(380px, 100%);
  visibility: hidden;
  opacity: 0;
}

.carrinho.aberto {
  visibility: visible;
  opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
  .carrinho {
    transform: translateX(100%);
    transition: transform 220ms ease-out, opacity 220ms ease-out, visibility 0s linear 220ms;
  }
  .carrinho.aberto {
    transform: translateX(0);
    transition: transform 220ms ease-out, opacity 220ms ease-out, visibility 0s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .carrinho {
    transition: opacity 120ms linear;
  }
}

Para quem não pediu menos movimento, o carrinho desliza da direita em 220 ms, mostrando que veio do ícone no canto. Para quem pediu, ele apenas esmaece rapidamente no lugar. Reduzir movimento não precisa significar zero transição: uma troca de opacidade curta não provoca o desconforto de um deslocamento grande. O visibility garante que, fechado, o painel não receba foco nem cliques.

JavaScript: a mesma preferência

Rolagem suave e animações feitas em JavaScript não obedecem à media query do CSS sozinhas. Consulte a preferência:

const reduzir = window.matchMedia('(prefers-reduced-motion: reduce)');

function irPara(elemento) {
  elemento.scrollIntoView({ behavior: reduzir.matches ? 'auto' : 'smooth', block: 'start' });
}

function confirmarItem(botao) {
  botao.textContent = 'Adicionado';
  if (!reduzir.matches) {
    botao.animate(
      [{ transform: 'scale(1)' }, { transform: 'scale(1.06)' }, { transform: 'scale(1)' }],
      { duration: 180, easing: 'ease-out' }
    );
  }
}

Repare que a informação está no texto ("Adicionado"), não no movimento. Com a animação desligada, a pessoa continua sabendo que o item entrou no carrinho. Esse é o teste mais importante de toda animação.

Pausa para o que se move sozinho

O banner do Bom Preço não gira mais sozinho para quem pediu menos movimento, e para os demais ganhou um botão "Pausar" visível, que também para quando o foco do teclado entra no banner. Rotação automática que não pode ser parada é exatamente o caso do critério 2.2.2.

Como testar a preferência de reduzir movimento

Ative no sistema e use a página de verdade. No Windows, a opção fica nas configurações de acessibilidade, em efeitos visuais, como "Efeitos de animação". No macOS e no iOS, em Acessibilidade, como "Reduzir movimento". No Android, também em acessibilidade, com o nome "Remover animações" na maioria das versões. Os nomes mudam um pouco entre versões, mas a busca das configurações encontra.

Para testar sem mexer no sistema, o painel Rendering do DevTools do Chrome permite emular a media feature prefers-reduced-motion. Abra a página, emule reduce e percorra os fluxos principais: abrir menu, adicionar ao carrinho, finalizar compra, rolar até o rodapé.

A animação também afeta desempenho. Anime transform e opacity, que os navegadores conseguem compor sem recalcular o layout da página inteira; animar width, top ou margin costuma travar em celular modesto. Mais sobre velocidade em site mais rápido: por onde começar.

Erros comuns

  • Animar tudo que entra na tela. A página parece ocupada e a pessoa espera os elementos pararem para ler.
  • Transições longas em ações frequentes. Um menu de 600 ms aberto vinte vezes por dia vira atraso perceptível.
  • Ignorar prefers-reduced-motion. Quem tem sensibilidade vestibular sente desconforto ou abandona o site.
  • Informação que só existe no movimento. Com a animação desligada, a confirmação some e a pessoa clica de novo.
  • Carrossel automático sem pausa. Compete com a leitura e descumpre o critério 2.2.2 das WCAG.
  • Animar propriedades de layout. Engasgos em aparelhos modestos, justamente onde a paciência é menor.

Checklist

  • Cada animação tem uma frase dizendo o que ela comunica.
  • Transições de interface estão por volta de 150 a 300 ms.
  • O CSS acrescenta movimento dentro de prefers-reduced-motion: no-preference.
  • Animações em JavaScript consultam matchMedia antes de rodar.
  • Tudo que se move sozinho tem botão de pausa.
  • Com a preferência ligada, nenhuma informação desaparece.
  • As animações usam transform e opacity.

Ligue "reduzir movimento" no seu sistema agora e faça uma compra ou cadastro completo no seu site: alguma coisa ainda desliza, gira ou some sem você saber se a ação deu certo?

Avalie este artigo

Referência: https://jitter.video/