Executando verificação de segurança...
1

Olá,

A analogia com SQL na view é forte. Mas no front-end moderno, a "separação de preocupações" virou separação de arquivos, não de responsabilidades.

O Tailwind troca a semântica das classes pela transparência visual: você vê exatamente o estilo sem sair do componente. E resolve dores reais em escala: CSS que não cresce indefinidamente, zero context switching e consistência forçada por design tokens.

  • Sem Tailwind: Você lê

    e precisa mapear o que .user-profile faz. Pode estar em um arquivo, pode estar em 5 arquivos, pode ter @apply ou media queries aninhadas. Você ganha "entendimento rápido" da semântica, mas perde a transparência visual.

  • Com Tailwind: Você lê

    . Você sabe exatamente como essa div se parece sem sair do arquivo. Você perde a semântica (user-profile), mas ganha transparência visual.

Não é necessariamente uma evolução, é troca de trade-offs. Pra quem preza arquitetura clássica, incomoda. Pra quem preza produtividade e manutenibilidade em times grandes, faz sentido.

E tá tudo bem odiar. Mas não é à toa que virou padrão.

Carregando publicação patrocinada...
2

Você está me dizendo que isso aqui tem transparência visual, é fácil de ler e é fácil de dar manutenção?

<form class="w-full max-w-xs space-y-3">
    <input type="email" placeholder="Email" class="h-11 w-full rounded-lg border border-border bg-secondary px-4 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary" value="">
    <input type="password" placeholder="Password" class="h-11 w-full rounded-lg border border-border bg-secondary px-4 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary" value="">
    <button type="submit" class="flex h-11 w-full items-center justify-center rounded-lg bg-primary text-sm font-normal text-primary-foreground transition-colors hover:bg-primary/90 active:scale-[0.98] disabled:opacity-60">Continue</button>
</form>

e que inclusive esse código é melhor que um componente como o abaixo?

<template>
  <form class="form">
    <input
      type="email"
      placeholder="Email"
      class="input"
      v-model="email"
    />

    <input
      type="password"
      placeholder="Password"
      class="input"
      v-model="password"
    />

    <button type="submit" class="button">
      Continue
    </button>
  </form>
</template>

<script setup>
import { ref } from 'vue'

const email = ref('')
const password = ref('')
</script>

<style scoped>
.form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.input {
  height: 44px;
  width: 100%;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--secondary);
  padding: 0 16px;
  font-size: 14px;
  color: var(--foreground);
  outline: none;
  transition: box-shadow 0.2s;
}

.input::placeholder {
  color: var(--muted-foreground);
}

.input:focus {
  box-shadow: 0 0 0 1px var(--primary);
}

.button {
  display: flex;
  height: 44px;
  width: 100%;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: var(--primary);
  font-size: 14px;
  font-weight: 400;
  color: var(--primary-foreground);
  border: none;
  cursor: pointer;
  transition: background 0.2s, transform 0.1s, opacity 0.2s;
}

.button:hover {
  background: color-mix(in srgb, var(--primary) 90%, black);
}

.button:active {
  transform: scale(0.98);
}

.button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
</style>

Qual dos dois você tem mais clareza?

Quando é uma mistureba com tudo no mesmo lugar, ou tudo separadinho?

1

O exemplo que você trouxe mostra o pior cenário possível: um bloco gigante de utilitários sem qualquer abstração. Ninguém defende isso como ideal.

A questão é que, na prática, esse formulário viraria um componente <AuthForm />. Dentro dele, você teria essas classes, mas quem consome o componente vê apenas:

<AuthForm />

A transparência visual está no momento da criação/manutenção do componente, não na leitura da estrutura principal. E a "mistureba" que você aponta no Tailwind é explícita e local. No CSS separado, a mistureba está espalhada em arquivos, com efeitos colaterais implícitos (herança, especificidade, classes que afetam elementos que você nem lembra que existem).

São trade-offs diferentes. Um prioriza isolamento e contexto local. O outro prioriza semântica e camadas arquiteturais. Nenhum é objetivamente "mais claro" em todo cenário.

1

Pessoa, são duas implementações diferentes para <AuthForm />

Vue é inteiro focado na separação de componentes e cada componente tem estilo, js e html separados dentro dele, isso facilita muito a manutenção futura.

Que manutenção o tailwind facilita? esse é o meu ponto geral.

Não existe um sistema que o componente é "criado e esquecido", Você vai ter que voltar a dar manutenção nos componentes, seja pra incluir mais coisas, arrumar algo que está quebrado

Tailwind ofereçe uma sobrecarga cognitiva insana para a manutenção.

1

Entendo seu ponto e concordo com ele. Mas a questão não é que uma seja "melhor" que a outra! são filosofias diferentes sobre onde a complexidade deve ficar.

Você diz que Tailwind tem sobrecarga cognitiva. Eu concordo que tem na escrita. CSS tradicional tem na manutenção:

  1. Alternar entre template e style a cada ajuste
  2. Rastrear herança e especificidade implícitas
  3. Classes reutilizadas em vários lugares com comportamentos distintos

Com Tailwind, o estilo está no elemento. Alterar padding é ir direto no elemento, não caçar qual classe controla o quê.

CSS tradicional otimiza leitura semântica. Tailwind otimiza edição local.

São trade-offs. Nenhum é objetivamente menos custoso! Cada um transfere o custo para um lugar diferente.

1

Uma dúvida, quando você aborda o tema de "manutenibilidade", porque você acredita que isso seja uma parte boa do Tailwind? Digo isso porque na minha opinião, acho mais simples ir na class ou no componente.styled e ver de fato o que ele faz ao invés de ter todas as informações centralizadas, me parece ser mais fácil de dar manutenção.

Além disso, nos seus projetos o Tailwind é aplicado diretamente no componente ou há uma abstração para que ele não polua os arquivos principais?

1

Primeiro:

O ponto não é que Tailwind seja inerentemente mais fácil de dar manutenção, mas que ele resolve dois problemas recorrentes em times grandes:

  1. CSS morto — com purge, o que não é usado simplesmente não vai parar na build. No CSS tradicional, ninguém tem coragem de deletar classes por medo de quebrar páginas que você não sabe que existem.

  2. Consistência — times grandes tendem a criar variações ad-hoc ("preciso de um padding de 13px aqui"). Tailwind força o uso de um sistema de design predefinido, reduzindo a entropia visual.

Segundo:

Nos projetos que uso, a regra é simples — componentes de UI (botões, inputs, cards) usam Tailwind diretamente. Páginas e seções compostas usam esses componentes. Nunca abstraio utilitários com @apply porque isso recria o problema do CSS tradicional só que com sintaxe pior. O "poluição" fica contida dentro do arquivo do componente, que é o único lugar onde aquele estilo importa.

1

No CSS tradicional, ninguém tem coragem de deletar classes por medo de quebrar páginas que você não sabe que existem.

Isso facilmente se resolve com Css Modules ou Scoped Style

1

Sim, CSS Modules e scoped style resolvem o problema de CSS morto e vazamento de escopo. Mas, não foi isso que eu quis dizer.

O ponto do "medo de deletar" não é sobre escopo, é sobre acoplamento implícito. Mesmo com scoped, quando você precisa alterar o padding do .input, vai lá no <style>, mexe, volta. Se esqueceu como o hover do botão se comporta, volta no <style>. Tailwind elimina esse vai-e-volta.

No fim, como disse CSS otimiza a leitura semântica. Tailwind otimiza a edição local.