- É possível implementar animações vinculadas à rolagem apenas com CSS, sem JS ou bibliotecas adicionais
- Com propriedades CSS como animation-timeline: scroll() / view(), a animação avança de acordo com a posição da rolagem ou a entrada na viewport
- A propriedade animation-range permite ajustar em detalhes em que trecho da viewport a animação começa e termina
- Para usuários sensíveis a movimento, é recomendável usar a media query prefers-reduced-motion
- Há suporte a partir do Safari 26 beta, ampliando bastante as possibilidades das animações de rolagem baseadas em CSS
Os 3 elementos das animações baseadas em rolagem
- Target: o elemento de destino ao qual a animação será aplicada (ex.: barra de progresso, imagem etc.)
- Keyframes: definem que mudança ocorrerá conforme a rolagem avança (igual ao
@keyframestradicional do CSS) - Timeline: determina quando e como a animação progride (baseada em rolagem/viewport, e não em tempo)
Timeline no CSS
- As animações CSS tradicionais usam por padrão a document timeline (baseada em tempo)
- Com a introdução da propriedade animation-timeline (CSS Animations Level 2, em 2023), a animação pode progredir com base não só no tempo, mas também em rolagem, entrada na viewport e outros critérios
timeline scroll()
- A timeline scroll() faz a animação avançar somente quando o usuário rola a página
- Exemplo: uma barra de progresso inferior que se preenche da esquerda para a direita conforme a rolagem
footer::after { content: ""; height: 1em; width: 100%; background: rgba(254, 178, 16, 1); left: 0; bottom: 0; position: fixed; animation: grow-progress linear; animation-timeline: scroll(); } @keyframes grow-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } } - animation-timeline deve ser definida depois da propriedade animation para funcionar corretamente
Considerações de acessibilidade de movimento
- Para proteger usuários sensíveis a movimento, recomenda-se usar a media query prefers-reduced-motion
@media not (prefers-reduced-motion) { /* código de animação */ }
timeline view()
- A timeline view() inicia a animação quando o elemento-alvo aparece na viewport
- Exemplo: ao rolar, a imagem desliza da direita e faz fade-in
@keyframes slideIn { 0% { transform: translateX(100%); opacity: 0; } 100% { transform: translateX(0%); opacity: 1; } } img { animation: slideIn; animation-timeline: view(); }
Controle do intervalo de progresso com animation-range
-
Por padrão,
animation-rangevai de 0% (entrada na viewport) a 100% (saída completa) -
Exemplo: fazer a animação avançar apenas até 50% da viewport
img { animation: slideIn; animation-timeline: view(); animation-range: 0% 50%; } -
É necessário definir valores de range adequados para uma boa experiência do usuário
-
Ao considerar acessibilidade de movimento, use junto com prefers-reduced-motion
@media not (prefers-reduced-motion) { img { animation: slideIn; animation-timeline: view(); animation-range: 0% 50%; } }
Uso avançado e próximos passos
scroll()eview()são funções e permitem definir várias opções, como o elemento scroller (padrão: nearest) ou o eixo (block,inline,x,y)- Com
animation-range,entry/exitetc., é possível criar uma UX mais refinada - O suporte inicial está disponível em navegadores mais recentes, como Safari 26 beta, com expectativa de padronização e expansão gradual do suporte no futuro
2 comentários
Parece que dá para implementar só com
animation-timeline. Que interessante!