Pular para o conteúdo
// visualizar em
salvo em todas as páginas

Tailwind CSS

Use o Camaleo junto com o Tailwind CSS v4. Ponha as camadas na ordem certa, transforme os tokens em utilitários e deixe o estilo fazer o trabalho dele.

// você vai aprender

  • Onde as camadas do Camaleo entram entre as do Tailwind, e por que a ordem importa
  • Como usar os tokens --cml-* como valores do tema do Tailwind
  • Como chegar a uma parte de um componente pelo data-slot
  • O que estilizar com utilitários e o que deixar para o estilo

O Camaleo não precisa do Tailwind: os estilos são CSS puro. Se o seu app já usa o Tailwind v4, os dois funcionam juntos com poucas linhas na folha de estilo principal. Não há plugin nem preset para instalar.

Ordene as camadas

Todo o CSS do Camaleo fica em quatro camadas: cml.tokens, cml.components, cml.style e cml.preferences. O Tailwind v4 usa theme, base, components e utilities. A camada declarada primeiro perde, então declare a ordem inteira uma vez, antes dos imports:

app/globals.css
@layer theme, base, cml, components, utilities;

@import "tailwindcss";
@import "@camaleo/styles/base.css";
@import "@camaleo/styles/glass.css";

Com essa ordem:

  • O reset do Tailwind (Preflight, em base) fica abaixo do Camaleo, então nunca achata os botões ou campos de um estilo.
  • Os seus utilitários ficam acima do Camaleo, então className="mt-6 w-full" num componente vence o espaçamento e a largura dele.
  • O CSS sem camada que você escreve continua vencendo tudo.
CUIDADO

Sem a primeira linha, quem decide é a ordem dos imports: as camadas do Camaleo vêm depois das do Tailwind e vencem até os seus utilitários, e um className="w-full" num Button parece não fazer nada.

Transforme tokens em valores do tema

Mapeie os tokens que você quer como utilitários num bloco @theme inline. Os nomes abaixo usam o prefixo cml- para nunca colidir com a paleta do Tailwind:

app/globals.css
@theme inline {
  --color-cml-surface: var(--cml-surface);
  --color-cml-raised: var(--cml-surface-raised);
  --color-cml-fg: var(--cml-fg);
  --color-cml-fg-secondary: var(--cml-fg-secondary);
  --color-cml-border: var(--cml-border);
  --color-cml-accent: var(--cml-accent);
  --color-cml-accent-fg: var(--cml-accent-fg);
  --color-cml-accent-text: var(--cml-accent-text);
  --color-cml-danger: var(--cml-danger);
  --radius-cml-control: var(--cml-radius-control);
  --radius-cml-surface: var(--cml-radius-surface);
  --font-cml-body: var(--cml-font-body);
  --font-cml-display: var(--cml-font-display);
}

Agora existem bg-cml-surface, text-cml-fg-secondary, border-cml-border, rounded-cml-surface e font-cml-display, e cada um segue o estilo, o modo e a marca do StyleProvider mais próximo:

app/page.tsx
<aside className="rounded-cml-surface border border-cml-border bg-cml-raised p-6">
  <h2 className="font-cml-display text-cml-fg">Seu plano</h2>
  <p className="text-cml-fg-secondary">Renova em 12 de novembro.</p>
</aside>
DICA

O inline faz diferença. Sem ele, o Tailwind declara --color-cml-surface no :root, onde ele é resolvido uma vez, com o estilo da raiz. Com inline, o utilitário escreve o próprio var(--cml-surface), e uma ilha em outro estilo ganha o valor dela.

Estilize as partes pelo data-slot

Toda parte de todo componente tem um data-slot estável, e o estado vem em atributos de dados (data-active, data-checked, data-disabled…). As variantes de dados do Tailwind chegam neles direto:

app/settings.tsx
{/* Um estado do próprio elemento */}
<Tab value="billing" className="data-active:font-semibold">Cobrança</Tab>

{/* Uma parte dentro do componente */}
<Card className="[&_[data-slot=card-title]]:text-lg">…</Card>

{/* Um token, só para este elemento */}
<Button className="[--cml-radius-control:0px]">Exportar</Button>

Cada página de componente lista slots, atributos de estado e tokens na seção Styling hooks.

Não brigue com o estilo

Utilitários são para o seu layout: margens, larguras, posição no grid, espaçamentos e a página em volta dos componentes. Isso não muda de um estilo para outro.

A aparência de um componente (cores, raio, bordas, sombras, fontes) é do estilo. Se você pinta um Button com bg-blue-600 rounded-full shadow-lg, ele para de mudar com o estilo, ignora a marca e o modo escuro, e o contraste dele deixa de ser conferido pelos testes da biblioteca.

QuerEm vez deUse
Um controle mais redondorounded-full[--cml-radius-control:999px]
A cor da marcabg-blue-600 text-whitebg-cml-accent text-cml-accent-fg
Texto mais apagadotext-gray-500text-cml-fg-secondary
Mudar só um estiloin-data-[style=retro]:…uma regra @scope no CSS

O guia Sobrescritas com escopo mostra como escrever essas regras.

CUIDADO

Uma variante como in-data-[style=retro]:uppercase vale para qualquer ancestral retro, inclusive um que fica fora de uma ilha aninhada em outro estilo. As regras de estilo do próprio Camaleo usam @scope ([data-style="retro"]) to ([data-style]), que para na ilha seguinte.

Modo escuro

Os tokens já trocam com o modo (usam light-dark()), então bg-cml-surface não precisa da variante dark:. O dark: do Tailwind segue o sistema por padrão. Se você define o mode e precisa do dark: para as suas cores, aponte a variante para o data-mode:

app/globals.css
@custom-variant dark (&:where([data-mode=dark], [data-mode=dark] *));

Essa variante só enxerga um mode="dark" explícito. Com mode="system" ou sem modo, mantenha o padrão do Tailwind, ou use tokens.

Antes de publicar

  • @layer theme, base, cml, components, utilities; vem antes de qualquer @import
  • Os tokens são mapeados com @theme inline, não com @theme simples
  • Utilitários em componentes só cuidam de layout e espaçamento
  • Mudanças de um estilo só ficam em regras @scope, não em variantes in-data-[style=…]
  • As cores que você acrescenta vêm de tokens, então seguem o modo e a marca
Esta página foi útil? · Editar esta página no GitHub