prefere-redução-movimento: às vezes, menos movimento é mais

A consulta de mídia prefers-reduced-motion detecta se o usuário solicitou no sistema operacional para minimizar a quantidade de animação ou movimento usado.

Nem todo mundo gosta de animações ou transições decorativas, e alguns usuários percebem movimentos doente ao se deparar com rolagem de paralaxe, efeitos de zoom e muito mais. A mídia de preferência do usuário a consulta prefers-reduced-motion permite criar uma variante de redução de movimento do seu site para usuários que expressaram essa preferência.

Compatibilidade com navegadores

  • Chrome: 74.
  • Borda: 79.
  • Firefox: 63.
  • Safari: 10.1.

Origem

Muito movimento na vida real e na Web

Outro dia, eu estava patinando no gelo com meus filhos. Era um dia lindo, o sol estava brilhando, e o gelo a pista estava lotada de pessoas ⛸. O único problema com isso: não me comporto bem com multidões. Com muitos alvos em movimento, não consigo me concentrar em nada e acabo perdida e me sinto completa sobrecarga visual, quase como olhar para um formigueiro 🐜.

Multidão de pés de pessoas patinando no gelo.
Sobrecarga visual na vida real.

Às vezes, o mesmo pode acontecer na Web: com anúncios que piscam, efeitos sofisticados de paralaxe, surpresas revelam animações, vídeos com reprodução automática e muito mais, a Web às vezes pode sobrecarregar Felizmente, diferente da vida real, existe uma solução para isso. A consulta de mídia CSS prefers-reduced-motion permite que os desenvolvedores criem uma variante de uma página para usuários que preferem movimento reduzido. Isso pode consistir em qualquer coisa, desde não ter vídeos de reprodução automática até a desativação de certos efeitos puramente decorativos ou a reformulação completa de uma página para determinados usuários.

Antes de abordar o recurso, deixe-me pensar sobre quais animações são usadas na Web. Se quiser, você também pode pular as informações contextuais e vá direto para os detalhes técnicos.

Animação na Web

Muitas vezes, a animação é usada para dar feedback ao usuário, por exemplo, para informar que uma ação foi recebida e está sendo processada. Por exemplo, em um site de compras, um produto poderia ser animada para "voar" em um carrinho de compras virtual, representado como um ícone no canto superior direito de o site.

Outro caso de uso envolve o uso de movimento para hackear a percepção do usuário usando uma mistura de telas de esqueleto, metadados contextuais e visualizações de imagens de baixa qualidade para ocupam muito tempo do usuário e fazem com que toda a experiência pareça mais rápida. A ideia é dar contexto para o usuário do que está por vir e, ao mesmo tempo, carregar tudo o mais rápido possível.

Por fim, há efeitos decorativos, como gradientes animados, rolagem paralaxe, plano de fundo vídeos e muitos outros. Embora muitos usuários gostem dessas animações, outros não gostam delas porque elas se sentem distraídas ou desaceleradas. Na pior das hipóteses, os usuários podem até sofrer de movimento como se fosse uma experiência da vida real, então para esses usuários, reduzir animações é uma forma médica necessidade.

Distúrbio do espectro vestibular acionado por movimento

Alguns usuários enfrentam distração ou náusea devido a conteúdo animado. Por exemplo, as animações de rolagem podem causar distúrbios vestibulares quando elementos diferentes do principal associado à rolagem se movem muito. Por exemplo, animações de rolagem paralaxe Pode causar distúrbios vestibulares porque os elementos de fundo se movem em uma velocidade diferente do primeiro plano os elementos. As reações a distúrbios vestibulares (ouvido interno) incluem tontura, náusea e enxaqueca. dores de cabeça e, às vezes, precisa de repouso na cama para se recuperar.

Remover movimento nos sistemas operacionais

Muitos sistemas operacionais tinham configurações de acessibilidade para especificar uma preferência por movimentos por muito tempo. As capturas de tela a seguir mostram a preferência de Reduzir movimento do macOS Mojave e Preferência de Remover animações do Android Pie. Quando marcadas, essas preferências fazem com que o sistema para não usar efeitos decorativos, como animações de inicialização de apps. Os aplicativos em si podem essa configuração também e remover todas as animações desnecessárias.

Tela de configurações do macOS com a opção "Reduzir movimento" está marcada.
A tela de configurações do Android com a opção "Remover animações" está marcada.

Remover movimento na Web

As consultas de mídia de nível 5 reduzem o movimento. a preferência do usuário pela Web. Consultas de mídia permitem que autores testem e consultem valores ou recursos do user agent ou do dispositivo de exibição, independentemente do documento que está sendo renderizado. A consulta de mídia prefers-reduced-motion é usado. para detectar se o usuário definiu uma preferência de sistema operacional para minimizar a quantidade de animação ou movimento que ela utiliza. Pode usar dois valores possíveis:

  • no-preference: indica que o usuário não deu preferência ao sistema operacional subjacente. sistema. Esse valor de palavra-chave é avaliado como false no contexto booleano.
  • reduce: indica que o usuário definiu uma preferência de sistema operacional indicando que devem minimizar movimento ou animação, de preferência ao ponto em que o movimento é removido.

Como trabalhar com a consulta de mídia de contextos CSS e JavaScript

Como acontece com todas as consultas de mídia, prefers-reduced-motion pode ser verificado a partir de um contexto CSS e de um Contexto do JavaScript.

Para ilustrar ambos, suponha que eu tenha um botão importante de inscrição no qual quero que o usuário clique. eu poderia definir uma "vibração" que chame a atenção mas, como um bom usuário da Web, só verei para os usuários que concordam explicitamente com animações, mas não com as outras pessoas, que podem ser usuários que desativaram as animações ou usuários em navegadores que não entendem a consulta de mídia.

/*
  If the user has expressed their preference for
  reduced motion, then don't use animations on buttons.
*/
@media (prefers-reduced-motion: reduce) {
  button {
    animation: none;
  }
}

/*
  If the browser understands the media query and the user
  explicitly hasn't set a preference, then use animations on buttons.
*/
@media (prefers-reduced-motion: no-preference) {
  button {
    /* `vibrate` keyframes are defined elsewhere */
    animation: vibrate 0.3s linear infinite both;
  }
}

Para ilustrar como trabalhar com a prefers-reduced-motion usando JavaScript, imagine que eu tenho uma animação complexa com a API Web Animations. Enquanto as regras CSS será acionada dinamicamente pelo navegador quando a preferência do usuário mudar, para JavaScript eu mesmo tenho que escutar as alterações e, em seguida, interromper manualmente minha execução, animações (ou reiniciá-las se o usuário permitir):

const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
mediaQuery.addEventListener('change', () => {
  console.log(mediaQuery.media, mediaQuery.matches);
  // Stop JavaScript-based animations.
});

Os parênteses ao redor da consulta de mídia real são obrigatórios:

O que não fazer
window.matchMedia('prefers-reduced-motion: reduce');
O que fazer
window.matchMedia('(prefers-reduced-motion: reduce)');

Como trabalhar com a consulta de mídia de contextos <picture>

Um caso de uso interessante é tornar a reprodução de um AVIF, WebP ou GIF animado dependente do media. Se (prefers-reduced-motion: no-preference) for avaliado como true, é seguro exibir a versão animada, senão a versão estática:

<picture>
  <!-- Animated versions. -->
  <source
    srcset="nyancat.avifs"
    type="image/avif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <source
    srcset="nyancat.gif"
    type="image/gif"
    media="(prefers-reduced-motion: no-preference)"
  />
  <!-- Static versions. -->
  <img src="nyancat.png" alt="Nyan cat" width="250" height="250" />
</picture>

Confira o exemplo abaixo. Tente alternar as preferências de movimento do dispositivo para conferir a diferença.

O famoso gato Nyan.

Descobrir as preferências do usuário no momento da solicitação

O cabeçalho de dica do cliente Sec-CH-Prefers-Reduced-Motion permite que os sites acessem as preferências de movimento do usuário, opcionalmente, no momento da solicitação; permitir que os servidores insiram o CSS correto inline por motivos de desempenho.

Demonstração

Criei uma pequena demonstração baseada no incrível trabalho de Rogério Vicente 🐈 gatos de status HTTP. Primeiro, tire um momento para apreciar a piada, é hilário, e eu vou esperar. Agora que você voltou, vou apresentar demonstração. Quando você rola, cada cat de status HTTP aparece alternadamente do lado direito ou esquerdo. 60 QPS e sem graça animação, mas, como descrito anteriormente, alguns usuários podem não gostar ou até ficar enjoados com o movimento, portanto está programada para respeitar prefers-reduced-motion. Isso funciona até mesmo dinamicamente, para que os usuários possam alterar suas preferências rapidamente, sem precisar recarregar. Se um usuário preferir o movimento reduzido, o as animações de revelação desnecessárias desaparecem, restando apenas o movimento normal de rolagem. A o seguinte screencast mostra a demonstração em ação:

Vídeo da prefers-reduced-motion de demonstração aplicativo

Conclusões

Respeitar as preferências do usuário é fundamental para os sites modernos, e os navegadores estão expondo cada vez mais recursos para que os desenvolvedores da Web façam isso. Outro exemplo lançado é prefers-color-scheme, que detecta se o usuário prefere um esquema de cores claro ou escuro. Você pode ler tudo sobre prefers-color-scheme no meu artigo Hello Darkness, My Old Friend 🌒.

O grupo de trabalho do CSS está padronizando mais consultas de mídia de preferência do usuário, como prefers-reduced-transparency (detecta se o usuário prefere transparência reduzida), prefers-contrast (detecta se o usuário solicitou que o sistema aumente ou diminua o contraste entre as cores adjacentes), e inverted-colors (detecta se o usuário prefere cores invertidas).

(Bônus) Forçando movimento reduzido em todos os sites

Nem todos os sites usam o prefers-reduced-motion ou talvez não sejam suficientes para você. Se você quiser, por qualquer motivo, interromper a movimentação em todos os sites, isso é possível. Uma forma de fazer isso acontecer é injetar uma folha de estilo com o seguinte CSS em cada página da Web que você visitar. há várias extensões do navegador (use por sua conta e risco) que permitam isso.

@media (prefers-reduced-motion: reduce) {
  *,
  ::before,
  ::after {
    animation-delay: -1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    background-attachment: initial !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
    transition-delay: -1ms !important;
  }
}

Dessa forma, o CSS anterior substitui a duração de todas as animações e transições. para tão pouco tempo que não são mais perceptíveis. Como alguns sites dependem de uma animação seja executada para funcionar corretamente (talvez porque uma determinada etapa dependa do acionamento da evento animationend), uma abordagem mais radical animation: none !important; não funcionaria. Mesmo a invasão anterior não é com a garantia de sucesso em todos os sites (por exemplo, ele não pode parar movimento que foi iniciado usando o API Web Animations), então confira e desative-a quando perceber uma falha.

Agradecimentos

Um agradecimento a Stephen McGruer, que implementou a prefers-reduced-motion no Chrome e, junto com Rob Dodson também analisou este documento. Imagem principal de Hannah Cauhepe no Unsplash.