Devs & IA

CSS moderno que dispensa JavaScript (e quando ainda precisa)

Anderson Ventura5 min de leitura

Existe um hábito que ficou de uma época em que o CSS não dava conta: puxar biblioteca para resolver coisa de interface. Acordeão, carrossel, transição de aba, elemento que aparece — tudo virava dependência.

Boa parte disso hoje é CSS. E a diferença não é ideológica: cada dependência é peso baixado, superfície de manutenção e uma versão que um dia vai conflitar com outra. Quando dá para não ter, é melhor não ter.

Este texto separa o que mudou do que continua exigindo JavaScript — com demonstrações rodando aqui na página.

Abrir e fechar sem medir altura

O clássico. Durante anos, expandir um bloco era um problema chato: height: auto não anima, então a saída era medir a altura com JavaScript e aplicar em pixels, ou usar max-height com um valor chutado — que fica errado quando o conteúdo cresce e produz aquele atraso estranho no fechamento.

Hoje o grid resolve. Uma linha de 0fr para 1fr anima até a altura real, sem ninguém precisar saber o valor:

Continua sendo animação de layout, que é a categoria cara — então use em um painel, não em quarenta itens de lista. Mas o JavaScript de medição sumiu, e com ele o bug de conteúdo dinâmico.

Revelar sem elemento extra por cima

Antes, revelar conteúdo por trás de uma faixa exigia um elemento sobreposto que era deslocado ou escondido. Mais um nó no HTML só para efeito visual.

Com clip-path, o recorte é do próprio elemento:

Sem nó extra, sem sobreposição, e o espaço já está reservado desde o primeiro quadro — nada empurra nada quando a animação termina.

Abas com marcador que acompanha

Este é o exemplo que mais surpreende quem não acompanhou o CSS dos últimos anos. Um grupo de abas com marcador deslizante, estado selecionado e troca de cor — sem uma linha de JavaScript.

A técnica usa input type="radio" escondido e o seletor de irmão para reagir ao que está marcado. O rótulo é um label ligado ao input, então clique e teclado funcionam de graça.

Onde isso não serve: se o conteúdo de cada aba vem do servidor, ou se a aba ativa precisa entrar na URL para ser compartilhável, você precisa de JavaScript de qualquer forma. Para abas de conteúdo já presente na página, o CSS entrega.

Trocar estado sem o layout pular

Um botão que vira "Salvo" depois do clique costuma causar um salto: o texto novo tem largura diferente, e o botão encolhe ou estica no meio da animação.

A solução é colocar os dois estados na mesma célula de grid. O botão nasce com a largura do texto mais longo e nada se mexe:

Continua precisando de JavaScript para trocar de estado de verdade — o que o CSS resolve é a transição não quebrar o layout.

Ícone que se transforma

Menu virando X. Antigamente, dois ícones e um trocando pelo outro. Hoje, as mesmas três barras giram e se cruzam:

A vantagem não é economizar bytes — é a continuidade. O olho acompanha o mesmo objeto mudando de forma, em vez de um elemento sumir e outro aparecer no lugar.

Esqueleto de carregamento

Blocos cinzas no formato do conteúdo que está por vir, com um brilho passando. Isso já foi biblioteca; hoje é um gradiente animado:

O detalhe que faz funcionar: o esqueleto precisa ter o mesmo formato do conteúdo real. Se as proporções não batem, a página pula quando o dado chega — e aí o esqueleto piorou a experiência em vez de melhorar, porque criou expectativa errada.

Onde o JavaScript continua necessário

Sendo honesto sobre o limite, porque "faça tudo em CSS" também é receita ruim.

Interpolar texto

CSS anima propriedade, não conteúdo. Um número que conta de zero até o total precisa de JavaScript — não tem como escapar:

Cascata em lista dinâmica

Dá para fazer cascata em CSS escrevendo o atraso de cada item à mão. Funciona até a lista mudar de tamanho — e listas mudam de tamanho. Quando o número de itens vem de dados, o atraso precisa ser calculado:

Reagir ao que está visível

Animar um bloco quando ele entra na tela precisa de IntersectionObserver. O CSS não sabe o que está visível.

Controlar progresso

Pausar, inverter, saltar para um ponto, sincronizar com rolagem. São capacidades de linha do tempo, e CSS não expõe controle assim.

O critério que eu uso

Se o efeito responde a hover, foco, ou a uma classe que o navegador já sabe alternar, tente CSS primeiro. Se depende de dado, de tempo ou de medir alguma coisa, é JavaScript.

Isso não é purismo. É que código sem dependência tem uma propriedade prática que nenhum framework entrega: você cola em qualquer projeto — React, Vue, WordPress, arquivo HTML solto — e funciona. Daqui a três anos ainda vai funcionar, porque não tem versão para atualizar.

Um aviso sobre suporte

Boa parte do que está aqui é relativamente recente. Antes de usar em produção, confira o suporte para o público que você atende — quem serve empresa com navegador antigo trava tem realidade diferente de quem faz produto para desenvolvedor.

A boa notícia é que quase tudo isso degrada bem: se o navegador não entende a animação, ele mostra o estado final. O conteúdo continua acessível, só sem o movimento. É bem melhor que uma biblioteca que quebra e leva a página junto.

Todas as peças usadas aqui estão no acervo de animações, com o código comentado e um filtro para ver só as que não precisam de biblioteca nenhuma.

CompartilharXLinkedInWhatsApp

Continue lendo