CategoriaCódigo e arquitetura
CSS puro ou framework utilitário: onde a regra mora
O preço de um framework utilitário não está nos bytes. Está nas decisões que você continua tomando, porque o valor de cada regra mora no HTML que você escreve. CSS nativo com token coloca a regra em um lugar e dá um nome a ela. A escolha é entre regra imposta e liberdade com disciplina.
Onde a regra de estilo mora em cada caminho
No caminho utilitário a regra mora na lista de classes do elemento. Um botão carrega px-4 py-2 text-sm bg-blue-600 no próprio HTML. A folha de estilo é saída gerada, então o HTML é a fonte da verdade.
A documentação do Tailwind (em inglês) descreve esse mecanismo. A ferramenta trata os arquivos de origem como texto puro e procura tokens que poderiam ser classes. Depois gera CSS para os tokens que reconhece e descarta o resto.
No caminho nativo a regra mora na folha de estilo, selecionada por classe ou por elemento. O HTML nomeia a intenção e a folha guarda o valor.
Essa diferença decide o que acontece quando você apaga uma tela. No caminho utilitário a regra vai embora junto com o HTML. No caminho nativo a regra fica no arquivo, sem uso e ainda interpretada.
Quem decide o valor visual
No caminho utilitário quem escreve o HTML decide. Duas telas podem sair com espaçamentos diferentes e nada na ferramenta impede.
No caminho de token o valor mora em uma variável de CSS. A MDN descreve as variáveis como forma de definir um valor em um lugar e referenciar em vários. A mesma página aponta o problema que elas removem, que é a cor repetida em muitas regras e o buscar e substituir a cada mudança.
Um arquivo de token define --space-4 uma vez. Um componente lê var(--space-4). A decisão sai do elemento e vai para a escala.
A diferença central é esta: um caminho decide elemento por elemento, o outro decide no token.
O que muda quando o design muda
Trocar a marca no caminho utilitário significa editar HTML. A cor da marca mora nos nomes de classe, então todo arquivo que a usa precisa mudar. Uma escala configurada ajuda apenas quando a mudança segue a escala.
Trocar a marca no caminho de token significa editar uma variável. Todo componente que lê a variável acompanha, sem tocar em arquivo de componente.
A mesma página da MDN registra um limite que vale saber. A função var() funciona só em valor de propriedade, então não serve dentro de media query nem de container query.
Dois recursos nativos cobrem o resto. Camadas de cascata decidem qual conjunto de regras vence sem subir a especificidade. A página da MDN sobre camada afirma que a primeira camada declarada tem a menor prioridade e a última tem a maior. A mesma página afirma que declaração normal fora de camada sobrepõe declaração normal em camada, e que declaração importante inverte essa ordem.
Container query (em inglês) estiliza um elemento pelo tamanho do contêiner, e a MDN as apresenta como alternativa às media queries. Um card se adapta dentro de uma barra lateral estreita sem breakpoint de viewport.
O que acontece quando entra gente nova no time
No caminho utilitário a pessoa nova lê o HTML e vê os valores. A convenção é imposta pelo build, porque a documentação do Tailwind avisa (em inglês) que nome de classe montado por concatenação não é detectado. Nome completo vira regra que a ferramenta verifica.
No caminho de token a pessoa nova lê a folha de estilo e o arquivo de token. A convenção é imposta pela revisão, e nada bloqueia um padding: 13px solto.
Aqui o jeito do time pesa mais que o gosto. Time grande com rotatividade ganha a regra de graça no caminho utilitário, e essa exigência é a heurística de consistência. O Nielsen Norman Group a enuncia como uma das dez (em inglês): a pessoa não deve se perguntar se duas telas significam a mesma coisa.
Time pequeno com um dono do design system ganha a regra no arquivo de token.
O que cada caminho cobra em manutenção
O caminho utilitário cobra em verborragia no HTML, em retrabalho quando a escala muda e em uma etapa de build. O ganho documentado é tamanho. O Tailwind afirma (em inglês) que gerar CSS a partir das classes em uso mantém a folha o menor possível.
O caminho de token cobra em nomenclatura e em poda. A página de performance da MDN (em inglês) afirma que todo estilo é interpretado, usado ou não no layout e na pintura. A mesma página afirma que seletor complexo aumenta tamanho de arquivo e tempo de parsing, e que o CSS bloqueia a renderização até o navegador decidir que precisa dele.
Regra sem uso que ninguém apaga continua nesse caminho crítico. É a conta que uma folha que só cresce paga todo mês.
O meio do caminho cobra uma decisão a mais por componente, e eu trato dele abaixo.
Quando o framework utilitário ganha
O framework utilitário ganha em quatro situações, e elas são comuns o bastante para nomear.
- Time grande com rotatividade alta, onde a regra não pode depender de quem escreveu o arquivo.
- Muitas telas parecidas montadas do mesmo conjunto pequeno de componentes.
- Prazo curto, onde a convenção de nomes é um custo que o time não paga agora.
- Produto cujo design muda pouco, então a escala fica estável.
O que se economiza é decisão, não bytes. O framework fixa os valores disponíveis e quem escreve o HTML escolhe um. Isso é economia real quando vinte pessoas mexem na mesma interface.
Essa economia tem preço. Você paga em HTML que esconde o valor e em uma folha que não se lê como documento de design.
O meio do caminho: CSS nativo com token e camada
Quase toda comparação para em duas opções. A terceira é uma folha organizada por token e por camada.
O arquivo de token guarda as escalas: cor, espaço, tipografia, raio e sombra. Variável de CSS dá nome a cada passo.
Na definição do Nielsen Norman Group (em inglês), um design system junta os padrões que permitem gerir design em escala. Em CSS, esses padrões viram valores no arquivo de token, e o componente lê dali.
As camadas guardam a ordem: token, base, componentes, utilitários. A MDN registra que a primeira camada declarada tem a menor prioridade e a última tem a maior, e que a prioridade inverte nas declarações marcadas como importantes.
Container query resolve componente que precisa se adaptar ao próprio espaço, não ao viewport.
O custo é uma convenção sua e uma revisão que a mantém. O ganho é mudança de design que toca um arquivo e HTML que continua legível.
Como decidir sem trocar de caminho a cada dois anos
Decida pensando em quem é dono do valor, não no framework da moda.
- Se o time não consegue impor convenção de nomes, fique com o framework utilitário.
- Se uma pessoa é dona do design system e as escalas mudam muito, fique com token.
- Se o produto tem dezenas de telas com estado compartilhado, a questão de CSS é secundária.
- Se o site é conteúdo, os dois caminhos custam mais do que as páginas merecem.
Depois escreva a decisão. Uma regra que você aponta sobrevive a uma pessoa nova e a uma moda nova.
Troque quando a realidade do time mudar, não porque saiu uma palestra nova. Tamanho do time, rotatividade, número de telas e velocidade de design são as entradas. Quando uma delas se move, revise a escolha.
Onde as fontes discordam
O Nielsen Norman Group puxa para dois lados no uso de cor. O artigo de hierarquia visual (em inglês) manda usar cor viva e saturada nos itens importantes e cor menos saturada nos itens de menor importância. O artigo de painéis e gráficos (em inglês) proíbe o mesmo movimento, porque as pessoas não percebem cores em uma ordem, então cor não deve carregar magnitude.
As duas regras valem quando o objeto muda. Uma página usa cor para marcar onde olhar primeiro. Um gráfico usa cor para marcar quanto, e essa leitura precisa de um canal ordenado. Um design system que mantém uma escala de cor para os dois trabalhos herda o conflito.
Os outros dois artigos concordam entre si. A heurística de consistência (em inglês) pede que o mesmo elemento signifique a mesma coisa entre telas. O artigo de design system (em inglês) pede que o time sustente um conjunto de padrões para componentes e padrões. Os dois descrevem o problema que um arquivo de token resolve. Nenhum diz se o token deve ser nome de classe ou variável de CSS.
Verifique antes de chamar de decidido
- Meça os bytes de CSS que a página carrega e a parte que ela usa.
- Procure na folha valores crus que deveriam ser token, como cor em hexadecimal e espaço em pixel.
- Troque um token e conte quantos arquivos mudam.
- Leia uma tela escrita por outra pessoa e veja se a regra é óbvia.
- Confirme que o build falha quando o nome de classe é montado por concatenação.
- Revise depois de um trimestre, porque o time e o produto se movem.
O framework não cobra em bytes. Cobra nas decisões que você continua tomando. O CSS nativo com token cobra em disciplina que alguém precisa manter. Escolha qual dessas contas o seu time vai pagar.
Fontes
- MDN, Using CSS custom properties
- MDN, @layer
- MDN, CSS container queries (em inglês)
- MDN, CSS performance optimization (em inglês)
- Tailwind CSS, Detecting classes in source files (em inglês)
- Nielsen Norman Group, Maintain Consistency and Adhere to Standards (em inglês)
- Nielsen Norman Group, Design Systems 101 (em inglês)
- Nielsen Norman Group, Visual Hierarchy in UX: Definition (em inglês)
- Nielsen Norman Group, Dashboards: Making Charts and Graphs Easier to Understand (em inglês)


