Tema animação simplificada — adeus clip-path circular, olá crossfade
lifelog·

Tema animação simplificada — adeus clip-path circular, olá crossfade

📖 3 min de leitura← Voltar para timeline

Passei a manhã inteira numa guerra contra animações de tema no LifeLog. E, como toda boa guerra contra CSS, terminei rendido — mas com um código muito melhor.

O problema

Desde que implementei o Theme Rail (aquele seletor lateral com 6 paletas + dark/light), eu usava uma animação circular com clip-path pra transicionar entre temas. A ideia era bonita: um círculo que expande do ponto de clique, revelando o novo tema por baixo, igual o Material Design. Na prática:

  • Chromium: a API View Transition nativa já faz crossfade, mas eu insisti em sobrescrever com clip-path no ::view-transition-new(root). Resultado: stutter visível porque o browser briga entre o VT nativo e a animação custom.
  • Firefox/Safari: o fallback usava um overlay com clip-path: circle() animado. Funcionava, mas o clip-path animado é pesado — troca de layout caro, especially no Firefox Mobile.

Teve hora que clicar no tema parecia um mini-freeze de 100ms. Imperceptível em desktop high-end, mas no celular era triste.

A solução: menos é mais

Depois de 3 commits iterando (f8cc2e2, 8155f4e, 4142f14 — cada um tentando polir a mesma abordagem), percebi que o problema era de design, não de implementação.

O que mudei:

  1. Chromium VT — parei de brigar com o clip-path e deixei o crossfade nativo do document.startViewTransition rolar. Zero stutter, zero código extra.
  2. Fallback (Firefox/Safari) — troquei o clip-path: circle() animado por um simples opacity com transition: 0.35s ease. Muito mais leve, sem repaint pesado.
  3. Scroll persistence — adicionei sessionStorage pra salvar a posição do scroll antes da navegação por language switch. Quando o usuário troca PT/EN, o scroll volta pro mesmo lugar — sem layout shift.

As tags também levaram love

Aproveitei o embalo e arrumei a visibilidade das tags nos cards. Antes usavam background: transparent que sumia no tema branco. Agora tão com color-mix(in srgb, var(--color-bg) 15%, transparent) — fundo sólido mas sutil, e o texto da tag usa a cor de destaque (accent) do projeto. Funciona em ambos os temas sem precisar de media query.

Stats da manhã

  • 6 arquivos alterados, 44 inserções, 52 deleções
  • ~100 linhas de CSS/JS a menos no PalettePicker
  • Zero stutter no toggle de tema — testado no Chromium, Firefox e Safari
  • E2E tests atualizados pro post count dinâmico e os novos parâmetros de busca (?q= em vez de ?tag=)

A lição do dia: animação complexa raramente vale o custo. Um crossfade bem feito é mais suave que um clip-path circle() que trava, por mais “bonito” que o círculo pareça no Figma.