Back

Scroll Suave com CSS scroll-behavior

Scroll Suave com CSS scroll-behavior

Clicar em um link âncora e ver a página saltar instantaneamente para uma seção parece abrupto. Isso desorienta os usuários, quebra o fluxo de leitura e faz com que a navegação interna pareça pouco refinada. A solução é uma única propriedade CSS — sem necessidade de bibliotecas JavaScript.

Principais Conclusões

  • A propriedade CSS scroll-behavior: smooth habilita rolagem animada para links âncora e APIs de rolagem programática sem nenhum JavaScript.
  • Aplique-a ao elemento html, não ao body, para que a propriedade se propague corretamente ao viewport.
  • A suavização (easing) e a duração controladas pelo navegador não podem ser personalizadas via CSS — recorra ao JavaScript apenas quando precisar de controle refinado.
  • Use scroll-margin-top para evitar que cabeçalhos fixos cubram os destinos das âncoras.
  • Envolva a regra em uma media query prefers-reduced-motion: no-preference para respeitar preferências de acessibilidade.

O Que É scroll-behavior e Como Funciona?

A propriedade CSS scroll-behavior controla como um contêiner de rolagem se move quando a rolagem é acionada programaticamente — através de links âncora, navegação por hash ou APIs JavaScript de rolagem como window.scrollTo() ou element.scrollIntoView().

Ela aceita dois valores:

  • auto — o padrão. Rola instantaneamente, sem animação.
  • smooth — anima a rolagem usando uma função de easing e duração definidas pelo navegador.

Um esclarecimento importante: scroll-behavior não afeta a rolagem acionada pela roda do mouse, trackpad ou arrasto da barra de rolagem do usuário. Ela se aplica apenas à rolagem programática e acionada por âncoras.

A suavização e a duração são totalmente controladas pelo navegador. Você não pode personalizá-las apenas com CSS. Se precisar de uma duração específica ou curva de easing personalizada, será necessária uma solução baseada em JavaScript.

Adicionando Rolagem Suave em CSS à Sua Página

Aplique scroll-behavior: smooth ao elemento html para habilitar a navegação com rolagem suave em toda a página:

html {
  scroll-behavior: smooth;
}

Use html, não body. Quando definida no elemento raiz, a propriedade se aplica ao viewport. Configurá-la no body não a propaga ao viewport — uma fonte comum de confusão quando a rolagem suave não funciona.

Esta declaração única gerencia toda a rolagem de links âncora automaticamente. Sem JavaScript, sem dependências.

Casos de Uso Práticos

Navegação em sumário (table of contents):

<nav>
  <a href="#intro">Introdução</a>
  <a href="#usage">Uso</a>
  <a href="#examples">Exemplos</a>
</nav>

Botão “voltar ao topo”:

<a href="#top">↑ Voltar ao topo</a>

Para que o link “voltar ao topo” chegue exatamente ao início da página, certifique-se de que exista um elemento com id="top" no começo da página, ou use href="#" como alternativa. Ambos os padrões funcionam imediatamente quando scroll-behavior: smooth está definido em html.

Lidando com Cabeçalhos Fixos com scroll-margin-top

Se seu layout incluir um cabeçalho fixo, os destinos das âncoras vão rolar parcialmente atrás dele. Corrija isso com scroll-margin-top:

:target {
  scroll-margin-top: 80px; /* corresponda à altura do seu cabeçalho */
}

Para uma cobertura mais ampla — incluindo rolagem programática para elementos que não são o :target atual — aplique a regra diretamente aos próprios elementos de seção:

section[id] {
  scroll-margin-top: 80px;
}

Isso desloca o ponto onde o navegador chega ao navegar para um elemento alvo — sem necessidade de JavaScript.

Acessibilidade: Respeitando prefers-reduced-motion

Alguns usuários sofrem de enjoo ou desconforto vestibular causado por rolagem animada. Sempre respeite a media query prefers-reduced-motion:

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

Esse padrão habilita a rolagem suave apenas para usuários que não optaram por desativar movimento nas configurações do sistema operacional. É a abordagem recomendada para uma UX de rolagem acessível.

Suporte dos Navegadores

scroll-behavior tem suporte universal em todos os navegadores modernos — Chrome 61+, Firefox 36+, Edge 79+, Safari 15.4+ e Opera 48+. O suporte global é de cerca de 95%, então nenhum polyfill é necessário para projetos atuais.

CSS vs. JavaScript: Qual Você Deve Usar?

NecessidadeMelhor Abordagem
Rolagem simples com links âncoraCSS
Duração ou easing personalizadoJavaScript
Rolagem condicional ou baseada em lógicaJavaScript

Para a maioria dos cenários de navegação interna — sites de documentação, landing pages, portfólios — o CSS é suficiente e preferível. Menos código, sem dependências, desempenho nativo do navegador.

Checklist Rápido de Implementação

  • ☐ Aplique scroll-behavior: smooth ao html, não ao body
  • ☐ Envolva-o em prefers-reduced-motion: no-preference
  • ☐ Adicione scroll-margin-top para layouts com cabeçalho fixo
  • ☐ Teste os links âncora e a navegação por teclado
  • ☐ Verifique o comportamento no Safari do iOS

Conclusão

A rolagem suave em CSS é uma daquelas melhorias que quase nada custa implementar e que imediatamente torna a navegação interna mais intencional. Uma declaração, posicionada corretamente, cobre a maioria dos casos de uso reais sem tocar em JavaScript.

FAQs

A propriedade scroll-behavior deve ser definida no contêiner de rolagem responsável pelo viewport, que é o elemento html. Quando aplicada ao body, o valor não se propaga ao scroller no nível do viewport, então a rolagem de links âncora recai no salto instantâneo padrão. Mova a regra para html e a animação suave funcionará como esperado.

Não. A duração da animação e a curva de easing são determinadas inteiramente pelo navegador e não podem ser personalizadas via CSS. Se seu design exige uma velocidade específica ou uma função de easing personalizada, você precisa de uma solução em JavaScript usando window.scrollTo com behavior smooth combinado com lógica de animação personalizada, ou uma pequena biblioteca que gerencie o tempo manualmente.

Não. A propriedade se aplica apenas à rolagem programática e acionada por âncora, como clicar em um link de hash, chamar scrollIntoView ou invocar window.scrollTo. A rolagem iniciada pelo usuário através da roda do mouse, gestos no trackpad, arrasto da barra de rolagem ou teclas de seta do teclado permanece inalterada e continua utilizando o comportamento de rolagem nativo do navegador.

Use a propriedade scroll-margin-top no elemento alvo com um valor igual à altura do seu cabeçalho. Por exemplo, definir scroll-margin-top como 80px em elementos section com id desloca a posição de chegada da rolagem para que a seção apareça abaixo do cabeçalho fixo, em vez de ficar escondida atrás dele. Nenhum JavaScript ou marcação extra é necessário.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay