Header fixo: CSS position: sticky e ocultar ao rolar
Guia de header fixo
Header fixo em CSS: position sticky, encolher e ocultar ao rolar | We.Inc
Crie um header fixo com position: sticky e depois adicione os modos encolher e ocultar ao rolar. Demo ao vivo, deslocamento de âncoras com scroll-margin, correções de z-index e um pequeno hook React.
Dê ao header position: sticky e top: 0, além de um fundo e um z-index, e ele fica preso no topo enquanto a página rola. Ele só gruda dentro do elemento pai, e um ancestral com overflow definido pode impedir isso. Para um header que some ao rolar, alterne uma classe com translateY a partir de um listener de scroll.
sticky vs fixed para headers
position: sticky
position: fixed
Ocupa espaço no layout
Sim
Não, adicione padding ao body
Fica preso em relação a
O ancestral rolável mais próximo
O viewport
Precisa de um inset como top: 0
Sim, senão age como relative
Normalmente
Cria um contexto de empilhamento
Sim
Sim
Para no fim do elemento pai
Sim
Não
Headers fixos são uma linha de CSS até deixarem de ser: o header se recusa a grudar, os links de âncora param embaixo dele ou um menu suspenso desliza para trás do conteúdo. Esta página mostra essa linha de CSS e depois cada uma dessas falhas, com uma demo de rolagem ao vivo em que você alterna entre os modos simples, encolher e ocultar.
Role dentro da caixa da demo. O header gruda nessa caixa, do mesmo jeito que um header de verdade gruda na página.
Mude o modo para encolher ou ocultar ao rolar e role de novo nas duas direções.
Clique em um link de seção na demo para ver o scroll-margin-top manter o título longe do header.
Copie o CSS e o hook que correspondem ao modo que você quer.
Se o sticky não faz nada, procure um ancestral com overflow: hidden, auto ou scroll. O header gruda nessa caixa em vez da página.
Um elemento sticky não consegue sair do elemento pai. Coloque o header direto no body ou em um wrapper tão alto quanto a página.
Dê ao header um fundo sólido ou levemente translúcido, senão o conteúdo vai aparecer através dele durante a rolagem.
Defina scroll-padding-top no html com a altura do header para que todo link de âncora e todo elemento focado pare abaixo dele.
Respeite a preferência por menos movimento: pule a animação de deslizar para quem pediu menos movimento.
Perguntas frequentes
Por que o meu position: sticky não funciona?
Três causas comuns: nenhum valor de inset como top: 0, um elemento pai que termina logo depois do header, sem espaço para grudar, ou um ancestral com overflow diferente de visible, que vira a caixa em que o header gruda. Verifique nessa ordem.
O header deve ser sticky ou fixed?
O sticky é mais simples porque mantém o seu lugar no layout, então nada pula para baixo dele no topo da página. O fixed é útil quando o header precisa ficar sobre um hero de tela cheia, mas aí você mesmo adiciona o padding à página.
Como evitar que os links de âncora fiquem escondidos sob um header fixo?
Adicione scroll-padding-top ao container de rolagem, normalmente o html, com valor igual à altura do header. Para alvos pontuais, você pode colocar scroll-margin-top no próprio título.
Por que o meu menu suspenso aparece atrás do conteúdo da página?
O posicionamento sticky cria um contexto de empilhamento, então tudo o que está dentro do header só consegue se empilhar dentro dele. Suba o próprio header com um z-index acima do conteúdo que vem depois, por exemplo z-index: 50, em vez de subir o menu suspenso.
Como o sticky funciona de verdade
Um elemento sticky começa no fluxo normal. Quando a rolagem o levaria além do seu inset, top: 0 no caso de um header, ele mantém essa posição até o fim do elemento pai chegar e empurrá-lo para fora.
A caixa em que ele gruda é o ancestral mais próximo com mecanismo de rolagem, o que inclui overflow: hidden. É por isso que um wrapper adicionado para recortar um carrossel pode quebrar, sem aviso, um header que está bem longe dele.
Ocultar ao rolar para baixo, mostrar ao rolar para cima
Compare a posição de rolagem atual com a anterior. Rolar para baixo além de um pequeno limite esconde o header com transform: translateY(-100%); qualquer movimento para cima o traz de volta.
Anime o transform em vez de top ou height, já que um transform não dispara layout. Escute o scroll com a opção passive para que o navegador nunca espere pelo seu handler.
Encolher sem pulos no layout
Mudar a altura do header enquanto ele está sticky move o conteúdo abaixo. Mantenha a altura externa fixa e encolha o logo com transform: scale, ou reduza o padding dentro de um header que já saiu do caminho.
Um atributo data, como data-scrolled no header, mantém as regras de estilo no CSS e reduz o script a uma linha.
O header fixo básico
Header fixo dentro de uma página com rolagem
Role o quadro. O header fica no topo e o link de âncora para abaixo dele graças ao scroll-padding-top.
Ocultar ao rolar para baixo, mostrar ao rolar para cima
CSS para os estados oculto e encolhido
O script só define atributos data. Toda mudança visual fica no CSS.
Hook React: useHideOnScroll
Retorna dois booleanos que você pode espalhar no header como atributos data. O limite de 8px ignora pequenas tremidas.
Armadilhas do header fixo
Sintomas e correções
Sintoma
Causa
Correção
O header sai rolando
Sem valor de top
Adicione top: 0
O header sai rolando
Um ancestral tem overflow: hidden
Passe o overflow para um wrapper menor, ou use overflow: clip
Gruda e depois sai cedo
O elemento pai é curto
Coloque o header no body ou em um wrapper de altura total
Títulos de âncora escondidos
Sem deslocamento de rolagem
scroll-padding-top no html
O menu fica atrás do conteúdo
Contexto de empilhamento do header baixo demais
z-index no próprio header
O conteúdo aparece através dele
Fundo transparente
Dê uma cor de fundo ao header
Sticky simples
Encolher
Ocultar ao rolar
Introdução
Recursos
Preços
Contato
Demo de rolagem ao vivo
Alterne entre simples, encolher e ocultar ao rolar, e depois role dentro da caixa.
Modo do header
Página de demo com rolagem
Marca
Role para baixo e depois volte um pouco para cima.