~/til/scroll-margin-top-depende-do-container-de-scroll

cat scroll-margin-top-depende-do-container-de-scroll.mdx

Âncoras quebram quando o scroll não é da janela

1 min de leitura

Um layout com altura fixa e overflow no main faz links de âncora pararem atrás do header fixo, e o scroll-margin-top precisa ser aplicado considerando esse container.

Meu layout tem altura de tela cheia, com o scroll acontecendo dentro do main e não na janela:

<div className="flex h-screen overflow-hidden">
  <AppSidebar />
  <main className="flex-1 overflow-y-auto">{children}</main>
</div>

Isso dá uma sensação de aplicação, e quebra duas coisas que normalmente funcionam de graça.

Títulos param atrás do header

Clicar em um link de âncora rola o título até o topo do container, exatamente onde fica o header fixo de 4rem. O título some atrás dele.

scroll-margin-top resolve, e o valor precisa considerar a altura do header:

.prose h2,
.prose h3 {
  scroll-margin-top: 5rem;
}

A propriedade vai no elemento de destino, não no container. Isso é contraintuitivo na primeira vez: você quer mexer no que rola, mas quem precisa do recuo é quem chega.

IntersectionObserver observa a janela por padrão

O segundo tropeço: para destacar a seção ativa em um índice lateral, o IntersectionObserver precisa saber qual é o container de scroll. O padrão é o viewport, e com o scroll no main nenhum título nunca entra ou sai de vista do ponto de vista dele.

const observer = new IntersectionObserver(callback, {
  root: document.querySelector("main"),
  rootMargin: "-80px 0px -70% 0px",
});

Sem o root, o callback dispara uma vez no carregamento e nunca mais.

LER~/til/scroll-margin-top-depende-do-container-de-scroll.mdxmdx · utf-8topo
cd ../til