A consulta de mídia "prefers-reduced-motion" detecta se o usuário pediu ao 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 sentem enjoo ao se deparar com rolagem paralaxe, efeitos de zoom e muito mais. A consulta de mídia de preferência do usuário prefers-reduced-motion permite criar uma variante com movimento reduzido do seu site para usuários que expressaram essa preferência.
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 a pista de patinação estava lotada de gente ⛸. O único problema é que eu não lido bem com multidões. Com tantas metas em movimento, não consigo me concentrar em nada e acabo me perdendo, com uma sensação de sobrecarga visual completa, quase como olhar para um formigueiro 🐜.
Às vezes, o mesmo pode acontecer na Web: com anúncios piscantes, efeitos de paralaxe sofisticados, animações de revelação surpreendentes, vídeos de reprodução automática e muito mais, a Web pode ser bastante avassaladora…
Felizmente, ao contrário da vida real, há 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 incluir desde evitar vídeos com reprodução automática até
desativar determinados efeitos puramente decorativos ou redesenhar completamente uma página para determinados usuários.
Antes de falar sobre o recurso, vamos voltar um pouco e pensar para que as animações são usadas na Web. Se quiser, você também pode pular as informações básicas e ir direto aos detalhes técnicos.
Animação na Web
A animação é usada com frequência para fornecer 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 pode ser animado para "voar" até um carrinho de compras virtual, representado como um ícone no canto superior direito do site.
Outro caso de uso envolve o uso de movimento para manipular a percepção do usuário usando uma mistura de telas esqueleto, metadados contextuais e prévias de imagens de baixa qualidade para ocupar muito tempo do usuário e fazer com que toda a experiência pareça mais rápida. A ideia é dar contexto ao usuário sobre o que está por vir e, enquanto isso, carregar as coisas o mais rápido possível.
Por fim, há efeitos decorativos, como gradientes animados, rolagem de paralaxe, vídeos em segundo plano e vários outros. Embora muitos usuários gostem dessas animações, alguns não gostam porque se sentem distraídos ou lentos por elas. No pior caso, os usuários podem até sofrer de enjoo como se fosse uma experiência da vida real. Portanto, para essas pessoas, reduzir as animações é uma necessidade médica.
Transtorno do espectro vestibular causado por movimento
Alguns usuários sentem distração ou náuseas com conteúdo animado. Por exemplo, 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 podem causar distúrbios vestibulares porque os elementos em segundo plano se movem em uma taxa diferente dos elementos em primeiro plano. As reações do distúrbio vestibular (ouvido interno) incluem tontura, náuseas e enxaquecas, e às vezes exigem repouso para recuperação.
Remover o movimento em sistemas operacionais
Muitos sistemas operacionais têm configurações de acessibilidade para especificar uma preferência por movimento reduzido há muito tempo. As capturas de tela a seguir mostram a preferência Reduzir movimento do macOS Mojave e a preferência Remover animações do Android Pie. Quando marcadas, essas preferências fazem com que o sistema operacional não use efeitos decorativos, como animações de inicialização de apps. Os aplicativos também podem e devem respeitar essa configuração e remover todas as animações desnecessárias.
Remover o movimento na Web
Media Queries Level 5 também traz para a Web a preferência do usuário por movimento reduzido. As media queries permitem que os autores testem e consultem valores ou recursos
do user agent ou do dispositivo de exibição, independente do documento renderizado. A media query
prefers-reduced-motion é usada
para detectar se o usuário definiu uma preferência do sistema operacional para minimizar a quantidade de animação ou
movimento usado. Ele pode ter dois valores possíveis:
no-preference: indica que o usuário não tem preferência no sistema operacional subjacente. Esse valor de palavra-chave é avaliado comofalseno contexto booleano.reduce: indica que o usuário definiu uma preferência de sistema operacional para que as interfaces minimizem o movimento ou a animação, de preferência até o ponto em que todo movimento não essencial seja removido.
Como trabalhar com a media query em contextos de CSS e JavaScript
Como em todas as media queries, prefers-reduced-motion pode ser verificado em um contexto de CSS e de JavaScript.
Para ilustrar os dois, suponha que eu tenha um botão de inscrição importante que quero que o usuário clique. Eu poderia definir uma animação "vibrar" que chama a atenção, mas, como um bom cidadão da Web, só vou reproduzir para os usuários que concordam explicitamente com animações, mas não para todos os outros, 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 prefers-reduced-motion em JavaScript, imagine que eu tenha definido uma animação complexa com a API Web Animations. Embora as regras de CSS
sejam acionadas dinamicamente pelo navegador quando a preferência do usuário muda, para animações
em JavaScript, preciso detectar as mudanças e interromper manualmente as animações
em andamento (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:
window.matchMedia('prefers-reduced-motion: reduce');
window.matchMedia('(prefers-reduced-motion: reduce)');
Como trabalhar com a media query de contextos <picture>
Um caso de uso interessante é fazer com que a reprodução de um AVIF, WebP ou GIF animado dependa do atributo
media. Se (prefers-reduced-motion: no-preference) for avaliado como true, será seguro
mostrar a versão animada. Caso contrário, 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 a seguir. Tente ativar e desativar as preferências de movimento do dispositivo para ver a diferença.
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 obtenham as preferências de movimento do usuário opcionalmente no momento da solicitação,
permitindo que os servidores incluam o CSS certo por motivos de desempenho.
Demonstração
Criei uma pequena demonstração com base nos incríveis
🐈 gatos de status HTTP de Rogério Vicente. Primeiro, reserve um momento para apreciar a piada. Ela é hilária, e eu vou esperar. Agora que você voltou, vamos apresentar a demonstração. Quando você rola a tela, cada gato de status HTTP aparece alternadamente do lado direito ou esquerdo. É uma animação suave de 60 FPS, mas, como descrito antes, alguns usuários podem não gostar dela ou até mesmo sentir enjoo. Por isso, a demonstração foi programada para respeitar prefers-reduced-motion. Isso funciona de forma dinâmica, para que os usuários possam
mudar a preferência na hora, sem precisar recarregar a página. Se um usuário preferir movimento reduzido, as animações de revelação não necessárias vão desaparecer, e apenas o movimento de rolagem normal vai permanecer. O
screencast a seguir mostra a demonstração em ação:
prefers-reduced-motion
Conclusões
Respeitar as preferências dos usuários é fundamental para os sites modernos, e os navegadores estão expondo cada vez mais
recursos para permitir 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ências do usuário, como prefers-reduced-transparency (detecta se o usuário prefere transparência reduzida), prefers-contrast (detecta se o usuário pediu ao sistema para aumentar ou diminuir a quantidade de contraste entre cores adjacentes) e inverted-colors (detecta se o usuário prefere cores invertidas).
(Bônus) Forçar o movimento reduzido em todos os sites
Nem todos os sites usam prefers-reduced-motion ou talvez não o suficiente para você.
Se você quiser parar o movimento em todos os sites, é possível fazer isso. Uma maneira de fazer isso é injetar uma folha de estilo com o seguinte CSS em todas as páginas da Web que você visita. Existem várias extensões de navegador (use por sua conta e risco!) que permitem 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;
}
}
O CSS anterior substitui as durações de todas as animações e transições
por um tempo tão curto que elas não são mais perceptíveis. Como alguns sites dependem de uma animação
para funcionar corretamente (talvez porque uma determinada etapa dependa do acionamento do
evento animationend),
a abordagem mais radical animation: none !important; não funcionaria. Mesmo o hack anterior não tem garantia de sucesso em todos os sites. Por exemplo, ele não pode interromper o movimento iniciado com a API Web Animations. Portanto, desative-o quando notar uma falha.
Recursos
- Último rascunho do editor da especificação Media Queries Level 5.
prefers-reduced-motionem Status da plataforma do Chrome.prefers-reduced-motionBug do Chromium.- Blink Postagem sobre a intenção de implementar.
Agradecimentos
Um grande agradecimento a Stephen McGruer, que implementou
prefers-reduced-motion no Chrome e, junto com
Rob Dodson, também revisou este documento.