
Tema animação simplificada — adeus clip-path circular, olá crossfade
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-pathno::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 oclip-pathanimado é 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:
- Chromium VT — parei de brigar com o
clip-pathe deixei o crossfade nativo dodocument.startViewTransitionrolar. Zero stutter, zero código extra. - Fallback (Firefox/Safari) — troquei o
clip-path: circle()animado por um simplesopacitycomtransition: 0.35s ease. Muito mais leve, sem repaint pesado. - Scroll persistence — adicionei
sessionStoragepra 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.