@apply no Tailwind: como usar e quando não usar
O @apply transforma um punhado de utilitários numa classe só. Onde isso ajuda de verdade, onde devolve o problema do CSS antigo e o que fazer no lugar.
@apply copia declarações de utilitários para um seletor CSS seu. Ele é útil na
fronteira com markup que você não controla e em uma regra pequena compartilhada;
não é o caminho obrigatório para “limpar” atributos longos.
O teste desta lição compilou quatro botões idênticos de duas maneiras. O resultado medido mostra que tamanho de bundle não decide sozinho; arquitetura e localidade do estilo pesam mais.
O compilador expande a lista linha por linha
Uma classe criada no CSS pode aplicar utilitários conhecidos:
.botao {
@apply rounded-lg bg-cyan-600 px-4 py-2 font-bold text-white;
}O CLI produziu CSS comum:
.botao {
border-radius: var(--radius-lg);
background-color: var(--color-cyan-600);
padding-inline: calc(var(--spacing) * 4);
padding-block: calc(var(--spacing) * 2);
font-weight: var(--font-weight-bold);
color: var(--color-white);
}O navegador não recebe @apply. O trabalho termina no build.
Use quando a fronteira não aceita classes
Conteúdo de terceiros pode entregar uma classe fixa, como .botao-compra, sem
permitir editar o HTML. Uma camada local com @apply adapta a saída ao sistema:
.widget-pagamento .botao-compra {
@apply rounded-lg bg-cyan-600 px-4 py-2 font-bold text-white;
}Outro caso é uma regra pequena que precisa participar de CSS comum:
.conteudo a {
@apply font-medium text-cyan-700 underline;
}Use seletor com alcance explícito. .btn global em toda aplicação vira uma API
informal que qualquer equipe pode ampliar sem contrato.
O problema volta quando a abstração cresce sem dono
Uma classe começa com seis utilitários, depois recebe tamanho, variante, ícone, loading e exceções. O HTML fica curto, mas a decisão volta a ficar distante.
.btn { @apply rounded-lg px-4 py-2 font-bold; }
.btn-primary { @apply bg-cyan-600 text-white hover:bg-cyan-700; }
.btn-danger { @apply bg-rose-600 text-white hover:bg-rose-700; }
.btn-small { @apply px-2 py-1 text-sm; }Quando combinações viram props e estados, isso já é componente. Extraia markup, acessibilidade e comportamento juntos. A lição de componentes Tailwind em React mostra essa fronteira.
Variantes podem aparecer no @apply
O compilador aceita variantes conhecidas na lista. Ainda assim, um seletor explícito às vezes comunica melhor a relação.
.botao {
@apply bg-cyan-600 hover:bg-cyan-700 focus-visible:outline-2;
}.botao:hover { background: var(--color-cyan-700); }
.botao:focus-visible { outline-width: 2px; }Escolha a forma que o time consegue depurar. O objetivo não é usar Tailwind em toda linha do CSS; é manter o sistema coerente.
Utility desconhecida interrompe o build
Aplicar um token que não existe gera erro. Reproduzi com
bg-clinica-500 sem declarar --color-clinica-500:
.cartao {
@apply bg-clinica-500;
}npx @tailwindcss/cli -i unknown.css -o unknown-output.cssO erro é útil: ele prova que o problema está no build, não na cascata do
navegador. Declare o token em @theme ou corrija
o nome.
Em CSS Modules, referência de tema exige cuidado
Cada módulo é processado separadamente e não conhece automaticamente o contexto de tema da folha principal. A documentação recomenda evitar misturar Tailwind e CSS Modules sem necessidade. Se precisar referenciar utilidades no módulo, importe a referência adequada ou prefira variáveis CSS comuns.
/* Cartao.module.css */
.raiz {
color: var(--color-slate-900);
}Não importe todo o Tailwind em cada módulo: isso multiplica processamento e pode duplicar CSS. Uma integração gradual pode manter módulos existentes e usar utilities no markup novo.
Quatro repetições não aumentaram as regras utility
Na versão de markup, quatro botões repetiram a mesma string. O compilador emitiu
cada utilitário uma vez. Na versão @apply, uma .btn reuniu as declarações.
<button class="rounded-lg bg-cyan-600 px-4 py-2 font-bold text-white hover:bg-cyan-700">
Salvar
</button>wc -c apply-markup.out.css apply-component.out.cssEm gzip, foram 1.767 contra 1.736 bytes. @apply ficou 31 bytes menor neste
caso. Isso não prova que ele é sempre menor: seletor, variantes, Preflight e
tema mudam o resultado. Prova apenas que repetir classes no HTML não repete as
regras no CSS final.
Três alternativas antes de criar uma classe global
Se o markup se repete com responsabilidade própria, extraia componente. Se só
um valor varia em runtime, use variável CSS. Se você precisa reduzir
especificidade de um seletor comum, use :where().
<button class="bg-(--cor-acao) text-white" style="--cor-acao:#0891b2">
Salvar
</button>Valores externos precisam ser validados antes de entrar em style. Uma variável
resolve valor dinâmico; não tente montar bg-${cor}-600, porque o scanner não
executa JavaScript.
Regra de decisão
Eu uso @apply quando preciso levar tokens Tailwind a um seletor CSS que já é a
interface de integração. Para componentes que controlo, deixo utilities no
markup e extraio um componente quando a repetição ganha comportamento. Essa
regra preserva a vantagem de ler estilo e estrutura juntos.
Sua missão é compilar os quatro botões nas duas formas, medir cru e gzip, depois adicionar uma variante de erro. Explique qual arquivo ficou mais fácil de alterar sem abrir exceção. Compare a decisão com o benchmark Tailwind, CSS puro e Modules antes de transformar um resultado pequeno em regra universal.
Revise a fronteira seis meses depois
Procure seletores com @apply e classifique-os: integração externa, conteúdo
gerado, primitiva visual ou componente disfarçado. Os dois primeiros costumam
continuar bons. Primitivas e componentes merecem revisão, porque podem ter
acumulado variantes, estados e exceções que o seletor não expressa bem.
Conte quantos lugares importam a folha e quantos componentes usam a classe. Uma regra global carregada por todo o produto para atender uma tela rara pode ser movida para a rota. Uma string utility repetida em vários arquivos pode indicar componente ausente. Nenhuma contagem decide sozinha; ela aponta onde ler.
Verifique também tokens de referência. Um @apply bg-marca pode parar de
funcionar quando o módulo é processado fora do contexto de tema. Prefira
variável CSS comum quando só precisa consumir um valor, e reserve @reference
ou integração específica para casos documentados da ferramenta. Não importe o
framework completo num módulo apenas para satisfazer uma declaração.
Ao final, registre uma regra curta no manual do projeto: quais fronteiras aceitam
@apply, quem aprova uma classe global e como medir o artefato. O
guia da trilha transforma essa decisão local em parte do
sistema, evitando que cada revisão reabra a mesma disputa abstrata.
Dúvidas e comentários
Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.
Entrar para perguntarÉ o mesmo login gratuito dos cursos.
Nenhuma dúvida por aqui ainda — a primeira pode ser a sua.
Todo o código deste artigo foi executado em @tailwindcss/cli 4.3.3 no Node 26.3.0, com gzip -9, e as saídas exibidas são as reais — como produzimos este conteúdo.
Fontes consultadas
- Tailwind CSS — Functions and directives — tailwindcss.com
- Tailwind CSS — Compatibility with CSS Modules — tailwindcss.com


