Um guia completo sobre o @scroll-timeline do CSS, abordando sua sintaxe, propriedades, uso e técnicas avançadas de animação. Aprenda a criar animações envolventes acionadas por rolagem para experiências web modernas.
Dominando o @scroll-timeline do CSS: Controle de Animação Através do Progresso da Rolagem
No cenário em constante evolução do desenvolvimento web, criar experiências de usuário envolventes e interativas é fundamental. O CSS oferece várias ferramentas para alcançar isso, e uma das mais poderosas, embora muitas vezes negligenciada, é a at-rule @scroll-timeline. Este recurso permite que os desenvolvedores vinculem animações diretamente ao progresso da rolagem de um elemento, criando animações cativantes acionadas pela rolagem. Este artigo fornece uma exploração abrangente do @scroll-timeline, abordando sua sintaxe, propriedades, uso prático e técnicas avançadas de animação para elevar seus designs da web.
O que é o @scroll-timeline do CSS?
@scroll-timeline é uma at-rule do CSS que define uma linha do tempo de rolagem, que é essencialmente uma sequência de estados que correspondem à posição de rolagem de um elemento especificado. Em vez de depender de animações tradicionais baseadas em tempo, o @scroll-timeline vincula o progresso da animação à ação de rolagem do usuário. Isso resulta em uma animação mais natural e responsiva, já que a velocidade da animação é controlada diretamente pelo comportamento de rolagem do usuário.
Isso abre possibilidades empolgantes para:
- Narrações visuais: Revelar conteúdo progressivamente à medida que o usuário rola a página.
- Visualização de dados interativa: Animar gráficos e tabelas enquanto o usuário explora os dados.
- Efeitos de paralaxe: Criar profundidade e dimensão animando diferentes elementos em velocidades variadas com base na posição da rolagem.
- Indicadores de progresso: Representar visualmente o progresso do usuário através de um documento longo.
Sintaxe e Propriedades
A sintaxe básica da at-rule @scroll-timeline é a seguinte:
@scroll-timeline nome-da-timeline {
source: auto | <seletor-de-elemento>;
orientation: auto | block | inline;
scroll-offsets: <deslocamento-de-rolagem>[ , <deslocamento-de-rolagem> ]*;
}
Vamos analisar cada propriedade:
timeline-name
Este é um identificador único para a sua linha do tempo de rolagem. Você usará este nome para referenciar a linha do tempo ao aplicá-la a uma animação.
Exemplo:
@scroll-timeline minha-scroll-timeline {
/* ... */
}
source
Esta propriedade especifica o elemento cuja posição de rolagem irá acionar a animação. Pode ter dois valores:
auto: O navegador determina automaticamente o elemento de rolagem. Geralmente, esta é a viewport do documento (a janela do navegador).<seletor-de-elemento>: Um seletor CSS que identifica o elemento específico a ser usado como fonte de rolagem. Isso permite que você direcione contêineres ou seções específicas em sua página.
Exemplo (usando a viewport como fonte):
@scroll-timeline minha-scroll-timeline {
source: auto; /* Usa a viewport */
/* ... */
}
Exemplo (usando um elemento específico como fonte):
@scroll-timeline minha-scroll-timeline {
source: #container-rolavel; /* Usa o elemento com ID "container-rolavel" */
/* ... */
}
orientation
Esta propriedade especifica a direção de rolagem a ser usada para a linha do tempo. Ela determina se a animação é acionada por rolagem vertical ou horizontal. Pode ter três valores:
auto: O navegador determina automaticamente a direção da rolagem com base na direção de rolagem dominante do elemento de origem.block: Usa a direção de rolagem do bloco (vertical, na maioria dos modos de escrita).inline: Usa a direção de rolagem em linha (horizontal, na maioria dos modos de escrita).
Exemplo (usando rolagem vertical):
@scroll-timeline minha-scroll-timeline {
source: auto;
orientation: block; /* Rolagem vertical */
/* ... */
}
Exemplo (usando rolagem horizontal):
@scroll-timeline minha-scroll-timeline {
source: #container-rolagem-horizontal;
orientation: inline; /* Rolagem horizontal */
/* ... */
}
scroll-offsets
Esta propriedade define as posições de rolagem que correspondem a pontos específicos na animação. É uma propriedade opcional e, se não for especificada, a animação será executada do início ao fim da área rolável. Quando usada, você pode definir um ou mais deslocamentos de rolagem, cada um especificando uma posição de rolagem e um ponto correspondente no progresso da animação.
A sintaxe para um <scroll-offset> é:
<scroll-offset> = <comprimento-percentagem> [ at <comprimento-percentagem> ]
Onde:
- O primeiro
<comprimento-percentagem>representa a posição de rolagem dentro da área rolável. - O
at <comprimento-percentagem>opcional representa o progresso da animação correspondente (0% a 100%). Se omitido, o progresso da animação é distribuído uniformemente entre os deslocamentos de rolagem definidos.
Exemplos:
/* Posição de rolagem de 200px corresponde a 0% de progresso da animação */
scroll-offsets: 200px at 0%;
/* Posição de rolagem em 50% da área rolável corresponde a 50% de progresso da animação */
scroll-offsets: 50% at 50%;
/* Múltiplos deslocamentos: */
scroll-offsets: 0px at 0%, 500px at 50%, 1000px at 100%;
/* Sem a palavra-chave "at" - progresso da animação distribuído uniformemente: */
scroll-offsets: 0px, 500px, 1000px; /* Equivalente a 0px at 0%, 500px at 50%, 1000px at 100% */
Considerações Importantes para scroll-offsets:
- Se você especificar
scroll-offsets, certifique-se de que eles cubram o intervalo da área rolável para evitar um comportamento inesperado da animação. - O progresso da animação é interpolado entre os deslocamentos de rolagem definidos.
- Se você não especificar
scroll-offsets, o progresso da animação será distribuído uniformemente por toda a área rolável.
Aplicando a Linha do Tempo de Rolagem a uma Animação
Depois de definir sua linha do tempo de rolagem, você precisa aplicá-la a uma animação CSS usando a propriedade animation-timeline.
A sintaxe é simples:
animation-timeline: nome-da-timeline; /* Use o nome que você definiu em @scroll-timeline */
Você também precisará definir uma animação CSS padrão usando @keyframes. A animação define as mudanças nas propriedades CSS que ocorrerão à medida que o usuário rola. Além disso, você vai querer garantir que a propriedade CSS `animation-range` esteja definida. Ela define o intervalo da linha do tempo de rolagem que ativará a animação.
Aqui está um exemplo completo:
/* Define a linha do tempo de rolagem */
@scroll-timeline minha-scroll-timeline {
source: auto;
orientation: block;
}
/* Define a animação */
@keyframes fade-in {
0% {
opacity: 0;
transform: translateY(20px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
/* Aplica a animação e a linha do tempo de rolagem a um elemento */
.elemento-animado {
animation: fade-in 1s forwards;
animation-timeline: minha-scroll-timeline;
animation-range: entry 25% cover 75%; /* entry e cover são valores de palavras-chave para os intervalos de início e fim */
}
Neste exemplo:
- A
@scroll-timelinechamadaminha-scroll-timelineé definida, usando a viewport como fonte e a rolagem vertical como orientação. - O
@keyframeschamadofade-indefine uma animação simples de aparecimento gradual e deslizamento para cima. - A classe
.elemento-animadotem a animaçãofade-inaplicada, mas em vez de ser acionada por um temporizador, ela é controlada pelaminha-scroll-timeline. - O `animation-range` define que a animação deve começar quando a borda superior do elemento entra nos 25% inferiores da viewport e terminar quando ele sai dos 25% superiores.
Exemplos Práticos e Casos de Uso
Vamos explorar alguns exemplos práticos de como você pode usar o @scroll-timeline para criar experiências web envolventes.
1. Revelando Conteúdo Progressivamente
Este é um caso de uso comum em que você revela conteúdo à medida que o usuário rola a página para baixo. Imagine um artigo longo com seções que aparecem gradualmente à medida que entram no campo de visão.
HTML:
<section class="secao-conteudo">
<h2>Seção 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>
</section>
<section class="secao-conteudo">
<h2>Seção 2</h2>
<p>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua...</p>
</section>
CSS:
@scroll-timeline reveal-timeline {
source: auto;
orientation: block;
}
@keyframes reveal {
0% {
opacity: 0;
transform: translateY(20px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.secao-conteudo {
animation: reveal 1s forwards;
animation-timeline: reveal-timeline;
animation-range: entry 25% cover 75%;
}
Neste exemplo, cada .secao-conteudo aparecerá gradualmente à medida que rola para dentro da viewport. O `animation-range` garante que a animação comece quando a borda superior da seção entra nos 25% inferiores da viewport e termine quando a seção sai dos 25% superiores.
2. Efeitos de Paralaxe
Efeitos de paralaxe criam uma sensação de profundidade movendo elementos de fundo em velocidades diferentes dos elementos de primeiro plano. O @scroll-timeline facilita a implementação da rolagem com paralaxe.
HTML:
<div class="container-paralaxe">
<div class="elemento-fundo"></div>
<div class="elemento-frente">
<h2>Seção de Paralaxe</h2>
<p>Algum conteúdo aqui...</p>
</div>
</div>
CSS:
.container-paralaxe {
position: relative;
height: 500px; /* Ajuste conforme necessário */
overflow: hidden;
}
.elemento-fundo {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('fundo.jpg'); /* Substitua pela sua imagem */
background-size: cover;
transform: translateZ(-1px) scale(2); /* Cria o efeito de paralaxe */
transform-origin: top;
pointer-events: none; /* Permite clicar nos elementos de primeiro plano */
animation: parallax-bg 1s linear forwards;
animation-timeline: parallax-timeline;
animation-range: 0vh 100vh;
}
.elemento-frente {
position: relative;
z-index: 1;
padding: 50px;
background-color: rgba(255, 255, 255, 0.8);
}
@scroll-timeline parallax-timeline {
source: auto;
orientation: block;
}
@keyframes parallax-bg {
0% { transform: translateZ(-1px) scale(2) translateY(0px); }
100% { transform: translateZ(-1px) scale(2) translateY(-50vh); }
}
Neste exemplo, o .elemento-fundo é posicionado atrás do .elemento-frente e ampliado usando transform. A animação `parallax-bg` é então aplicada, fazendo com que o fundo se mova mais lentamente que o primeiro plano à medida que o usuário rola, criando o efeito de paralaxe. O `animation-range` garante que a animação seja executada por toda a altura da viewport (0vh a 100vh).
3. Animando uma Barra de Progresso
Você pode usar @scroll-timeline para criar uma barra de progresso que representa visualmente o progresso da rolagem do usuário através de um documento.
HTML:
<div class="container-barra-progresso">
<div class="barra-progresso"></div>
</div>
<div class="conteudo">
<!-- Seu conteúdo aqui -->
</div>
CSS:
.container-barra-progresso {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 5px;
background-color: #eee;
z-index: 1000;
}
.barra-progresso {
height: 100%;
width: 0%;
background-color: #007bff;
animation: preenchimento-barra-progresso 1s linear forwards;
animation-timeline: scroll-timeline-documento;
}
@scroll-timeline scroll-timeline-documento {
source: auto;
orientation: block;
}
@keyframes preenchimento-barra-progresso {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
Neste exemplo, a largura da .barra-progresso é animada de 0% a 100% à medida que o usuário rola pelo documento. A @scroll-timeline é nomeada como `scroll-timeline-documento`, deixando claro o que ela representa.
Técnicas Avançadas
Depois de dominar o básico, você pode explorar algumas técnicas avançadas para criar animações acionadas por rolagem ainda mais sofisticadas.
1. Usando scroll-offsets para Controle Preciso
A propriedade scroll-offsets permite mapear posições de rolagem específicas para valores de progresso de animação específicos. Isso é útil quando você deseja acionar certos estados de animação em pontos precisos durante a rolagem.
@scroll-timeline timeline-personalizada {
source: #container-rolavel;
orientation: block;
scroll-offsets: 100px at 0%, 500px at 50%, 1000px at 100%;
}
@keyframes animacao-personalizada {
0% {
transform: translateX(-100px);
opacity: 0;
}
50% {
transform: translateX(0);
opacity: 1;
}
100% {
transform: translateX(100px);
opacity: 0;
}
}
.elemento-animado {
animation: animacao-personalizada 1s forwards;
animation-timeline: timeline-personalizada;
}
Neste exemplo, a animação irá:
- Começar em
translateX(-100px)eopacity: 0quando a posição de rolagem for 100px. - Atingir
translateX(0)eopacity: 1quando a posição de rolagem for 500px. - Terminar em
translateX(100px)eopacity: 0quando a posição de rolagem for 1000px.
2. Combinando com JavaScript
Embora o @scroll-timeline ofereça um controle de animação poderoso através de CSS, você pode combiná-lo com JavaScript para ainda mais flexibilidade. Por exemplo, você pode usar JavaScript para:
- Calcular e atualizar dinamicamente
scroll-offsetscom base no tamanho da viewport ou em mudanças de conteúdo. - Acionar efeitos ou interações adicionais baseados em JavaScript com base no progresso da rolagem.
- Implementar soluções de fallback para navegadores que não suportam totalmente o
@scroll-timeline.
Aqui está um exemplo básico de como usar JavaScript para ler o progresso da rolagem e atualizar uma variável CSS:
const elementoRolavel = document.getElementById('container-rolavel');
const elementoAnimado = document.querySelector('.elemento-animado');
elementoRolavel.addEventListener('scroll', () => {
const posicaoRolagem = elementoRolavel.scrollTop;
const rolagemMaxima = elementoRolavel.scrollHeight - elementoRolavel.clientHeight;
const porcentagemRolagem = (posicaoRolagem / rolagemMaxima) * 100;
elementoAnimado.style.setProperty('--scroll-progress', porcentagemRolagem + '%');
});
Você pode então usar esta variável CSS em sua animação:
@keyframes animacao-personalizada {
0% {
transform: translateX(calc(var(--scroll-progress) * -1px));
}
100% {
transform: translateX(calc(var(--scroll-progress) * 1px));
}
}
.elemento-animado {
--scroll-progress: 0%; /* Valor inicial */
animation: animacao-personalizada 1s linear forwards;
animation-timeline: scroll-driven-timeline;
}
3. Aproveitando Diferentes Funções de Easing
Embora animation-timing-function não seja diretamente aplicável à própria linha do tempo de rolagem (já que a linha do tempo é acionada pelo progresso da rolagem, não pelo tempo), você ainda pode usar funções de easing em seus @keyframes para controlar a velocidade e o ritmo da animação em diferentes estágios. Experimente com diferentes funções de easing como ease-in, ease-out, ease-in-out, ou até mesmo curvas de bezier cúbicas personalizadas para alcançar o efeito desejado.
Compatibilidade de Navegadores e Fallbacks
Até o final de 2023, o @scroll-timeline desfruta de um suporte relativamente bom em navegadores modernos como Chrome, Edge, Firefox e Safari. No entanto, é essencial verificar o status de compatibilidade atual em sites como Can I use... antes de implementá-lo em produção.
Para navegadores que não suportam @scroll-timeline, você pode fornecer um fallback usando ouvintes de eventos de rolagem tradicionais baseados em JavaScript e bibliotecas de animação como GSAP (GreenSock Animation Platform) ou Anime.js. Você também pode usar media queries de recursos CSS (@supports) para aplicar condicionalmente as animações baseadas em @scroll-timeline ou os fallbacks baseados em JavaScript.
@supports (animation-timeline: scroll()) {
/* Aplica animações baseadas em @scroll-timeline */
.elemento-animado {
animation: fade-in 1s forwards;
animation-timeline: minha-scroll-timeline;
}
} @else {
/* Aplica fallback baseado em JavaScript */
.elemento-animado {
/* Oculta inicialmente */
opacity: 0;
}
/* (Código JavaScript para detectar rolagem e aplicar opacidade) */
}
Considerações de Acessibilidade
Ao usar @scroll-timeline ou qualquer técnica de animação, é crucial considerar a acessibilidade. Certifique-se de que suas animações não causem:
- Convulsões: Evite animações que piscam ou mudam rapidamente.
- Distração: Forneça uma maneira para os usuários pausarem ou desativarem as animações, especialmente se forem longas ou distrativas.
- Sobrecarga cognitiva: Use animações com moderação e certifique-se de que elas sirvam a um propósito claro, em vez de serem puramente decorativas.
- Enjoo de movimento: Tenha cuidado com os efeitos de paralaxe, pois eles podem desencadear enjoo de movimento em alguns usuários.
Considere fornecer maneiras alternativas de acessar as informações apresentadas através de animações, como conteúdo estático ou texto descritivo. Use atributos ARIA para fornecer significado semântico e contexto para tecnologias assistivas.
Melhores Práticas
Aqui estão algumas melhores práticas a serem lembradas ao trabalhar com @scroll-timeline:
- Use nomes de timeline descritivos: Escolha nomes de timeline que indiquem claramente seu propósito (por exemplo,
parallax-background-timeline,reveal-section-timeline). - Mantenha as animações performáticas: Otimize suas animações para evitar gargalos de desempenho. Use propriedades CSS aceleradas por hardware como
transformeopacitysempre que possível. - Teste exaustivamente: Teste suas animações em diferentes dispositivos e navegadores para garantir que funcionem como esperado e não causem problemas de acessibilidade ou desempenho.
- Comece Simples: Comece com animações simples e adicione complexidade gradualmente à medida que ganha experiência.
- Considere a Experiência do Usuário: Garanta que suas animações melhorem a experiência do usuário, não a prejudiquem. Evite animações excessivamente complexas ou distrativas.
- Use a propriedade CSS `animation-range`: Garanta que as animações só sejam acionadas quando um elemento estiver na viewport para uma experiência suave e previsível.
Conclusão
@scroll-timeline é um recurso poderoso do CSS que permite aos desenvolvedores criar animações envolventes e interativas acionadas por rolagem. Ao vincular animações ao comportamento de rolagem do usuário, você pode criar experiências web mais naturais e responsivas. Ao entender sua sintaxe, propriedades e técnicas avançadas, você pode aproveitar o @scroll-timeline para elevar seus designs da web e criar jornadas de usuário cativantes. Lembre-se de considerar a compatibilidade do navegador, acessibilidade e desempenho ao implementar o @scroll-timeline, e sempre priorize a experiência do usuário.