Scroll-Driven Animations: Animações CSS Guiadas pelo Scroll

Como animation-timeline, scroll() e view() ligam o progresso de uma animação CSS à posição de rolagem em vez do tempo, permitindo barras de progresso, efeitos de parallax e elementos que aparecem ao entrar na tela sem JavaScript.

Barras de progresso de leitura, efeitos de parallax, elementos que aparecem ao entrar na tela: até pouco tempo atrás, tudo isso exigia um listener de scroll em JavaScript recalculando posições a cada frame. As Scroll-Driven Animations movem esse trabalho inteiro para o CSS, ligando o progresso de uma animação diretamente à posição de rolagem em vez do tempo, através da propriedade animation-timeline.

Como funciona

Toda animação CSS precisa de uma "linha do tempo" que dita seu progresso. Por padrão, essa linha do tempo é o relógio: a animação avança conforme os segundos passam. A propriedade animation-timeline troca esse relógio por uma linha do tempo baseada em scroll, usando uma de duas funções:

Barra de progresso de leitura com scroll()

O exemplo mais direto é uma barra fixa no topo que se enche conforme a página rola:

.barra-progresso {
    position: fixed;
    top: 0;
    left: 0;
    height: 4px;
    background: royalblue;
    transform-origin: left;
    animation: crescer linear;
    animation-timeline: scroll(root);
}

@keyframes crescer {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
}

Aqui, scroll(root) liga a animação à rolagem do documento inteiro. Não existe duração real — o keyframe 0% corresponde ao topo da página e 100% ao fim, e o navegador interpola conforme o usuário rola.

Elementos que aparecem ao entrar na tela com view()

Para animar um elemento no momento em que ele entra na área visível — um efeito muito comum em landing pages — a função view() é mais adequada, pois sua linha do tempo é relativa à visibilidade do próprio elemento, não à rolagem da página inteira:

.card {
    animation: aparecer linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 40%;
}

@keyframes aparecer {
    from {
        opacity: 0;
        transform: translateY(40px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

A propriedade animation-range recorta em que trecho da entrada do elemento a animação deve rodar — nesse caso, do instante em que ele começa a entrar na viewport até cobrir 40% dela, terminando a animação bem antes do elemento ficar totalmente visível.

Efeito parallax

Combinando scroll() com uma imagem de fundo maior que o container, dá para simular parallax sem nenhum JavaScript:

.hero {
    overflow: hidden;
}

.hero img {
    animation: subir linear;
    animation-timeline: scroll(root);
    animation-range: entry-crossing 0% exit-crossing 100%;
}

@keyframes subir {
    from { transform: translateY(-10%); }
    to { transform: translateY(10%); }
}

Nomeando containers de scroll

Quando a rolagem não acontece no documento inteiro, mas dentro de um container específico (um carrossel, por exemplo), é possível nomear esse container com scroll-timeline-name e referenciá-lo de qualquer elemento filho:

.carrossel {
    overflow-x: auto;
    scroll-timeline: --scroll-carrossel x;
}

.indicador {
    animation: mover-indicador linear;
    animation-timeline: --scroll-carrossel;
}

Quando usar

Cuidados

Como não existe duração em tempo real, propriedades como animation-duration não fazem sentido aqui — quem controla o "tamanho" da animação é o próprio intervalo de rolagem, ajustado com animation-range. Vale também respeitar prefers-reduced-motion, desabilitando ou simplificando essas animações para quem prefere menos movimento na tela. Em navegadores sem suporte, a animação simplesmente não roda e o elemento fica no seu estado final de CSS — por isso é importante que o layout continue legível sem a animação, tratando-a como um reforço visual e não como algo essencial ao conteúdo.

Compatibilidade

O suporte já é bom nos navegadores baseados em Chromium e mais recente no Firefox e no Safari. Vale checar o suporte atual antes de depender dessa técnica como única forma de exibir conteúdo importante.

caniuse

Conclusão

As Scroll-Driven Animations tiram do JavaScript um tipo de animação que sempre foi trabalhoso de sincronizar manualmente com a rolagem, entregando o cálculo de progresso para o próprio navegador. O resultado são animações mais suaves, que rodam fora da thread principal, com bem menos código do que a alternativa baseada em scroll e IntersectionObserver.

Tecnologia:
css

Deixe seu Comentário!

Dúvida, sugestão ou só um "valeu!" — tudo é bem-vindo por aqui.

Comentário
Nome
Email
lock Seu e-mail não será publicado.