Transições externas: o que funciona e o que não funciona
O assunto é simples quando você entende como o navegador lida com elementos que ficam fora do contêiner principal. Mas na prática, isso consome mais tempo do que deveria porque poucas pessoas leem a documentação sobre overflow hidden antes de tentar aplicar efeitos. Eu já perdi uma tarde inteira tentando fazer um card com hover effect que desaparecia quando passava para fora da div pai. O problema era que eu tinha colocado umtransform: scale() no elemento filho, mas o container pai tinha overflow: hidden. O browser corta tudo que sai dos limites, isso é padrão. Funciona assim há anos.
Elementos de transição externa na prática
A regra básica é que transições que escapam do contêiner são cortadas quando há overflow oculto. Se você quer que um elemento cresça, gire ou se mova para fora do lugar dele, precisa remover essa restrição. A solução é simples: deixe o container com overflow: visible ou use position: relative no elemento pai. Outro problema comum é que transforms criam novos contextos de empilhamento. Quando você aplica transform em um elemento, ele automaticamente vira um contêiner para filhos com overflow: hidden, mesmo que você não tenha colocado isso intencionalmente. Isso mata muitas animações que deveriam funcionar.
A workaround que eu uso hoje é adicionar um wrapper ao redor do elemento animado, colocar o wrapper com position: absolute e z-index: alta, e deixar o container original com overflow normal. O elemento transiciona fora do lugar dele mas não é cortado pelo pai.
Problemas que ninguém conta
Primeiro, tem o caso de elementos fixos (position: fixed). Eles literalmente saem do contexto de empilhamento do pai. Isso significa que qualquer transição neles ignora completamente o overflow do container. Isso pode ser útil ou problemático, dependendo do que você quer. Segundo, elementos com will-change criam camadas separadas de composição. O navegador trata isso como um elemento novo em alguns casos, e aí suas transições podem se comportar de forma inesperada. Remova o will-change se algo não estiver funcionando como esperado.
Terceiro, tem o problema de scroll-behavior em containers. Se o container pai tem scroll e você anima um elemento que sai dele, o scroll se comporta de forma estranha. Eu já vi elementos pularem para dentro do container de novo durante a animação.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Quando NÃO usar
Não adianta forçar transições externas em layouts que precisam de performance. Se você tem 50 elementos animando ao mesmo tempo saindo dos containers, o browser vai travar. Isso acontece especialmente em mobile. Também não funciona bem quando você precisa de clipping preciso. Se o design exige que o elemento fique exatamente dentro dos limites, transições externas vão criar problemas visuais. Use clip-path ou mask-image nesses casos.
Código prático
.container {
position: relative;
overflow: visible;
}
.elemento-animado {
position: relative;
transition: transform 0.3s ease;
}
.elemento-animado:hover {
transform: scale(1.1) translateX(20px);
}
Se o elemento ainda estiver sendo cortado, verifique se algum ancestral tem overflow: hidden ou transform aplicado. Um desses é suficiente para matar a animação. Também recomendo usar requestAnimationFrame se precisar de sincronização com o frame rate. Transições CSS normais podem ficar dessincronizadas em monitores com refresh rates altos.
Alternativas
Se transições externas não funcionam no seu caso, existem alternativas. clip-path permite animar a forma do elemento sem sair do contexto. mask-image funciona de forma similar mas com mais controle. Para efeitos de partículas ou múltiplos elementos, considere usar WebGL diretamente. Isso evita o problema de contexto de empilhamento completamente, mas tem uma curva de aprendizado maior.
Em resumo, elementos de transição externa funcionam quando você entende como o navegador resolve o overflow. Teste em cada container individualmente e verifique os ancestrais.