Variaveis CSS com Claude Code: tokens de tema praticos
Use Claude Code para implementar variaveis CSS, var(), tokens de tema, modo escuro e revisoes de UI.
Variaveis CSS transformam estilo em sistema
Variaveis CSS, chamadas oficialmente de propriedades personalizadas CSS, permitem declarar valores como --color-accent e reutiliza-los com var(--color-accent). Em linguagem simples, sao lugares com nome para guardar cores, espacamentos, raios, sombras, tamanhos de fonte e variacoes de estado.
Isso muda bastante o trabalho com Claude Code. Se voce pedir apenas “crie um card bonito”, o CSS gerado pode ter cores repetidas em varios seletores. Se voce pedir primeiro os tokens de tema, Claude Code passa a trabalhar com uma camada estavel. Modo escuro, teste de CTA, marca de cliente e estado de erro viram substituicoes de token, nao uma refatoracao inteira.
Para completar o contexto, veja tambem modo escuro, sistema de design e padroes Flexbox. O modelo mental e: tokens de paleta guardam valores crus, tokens semanticos explicam o significado no produto, tokens de componente adaptam uma parte da UI e tokens de estado cobrem dark, danger, compact ou brand.
Peça tokens antes da interface
Este prompt reduz valores soltos e obriga Claude Code a criar uma base reutilizavel.
{
"task": "Create CSS custom properties for an article UI and implement a copy-paste demo.",
"mustInclude": [
"palette tokens",
"semantic theme tokens",
"component-level tokens",
"var() fallbacks",
"dark mode with data-theme and prefers-color-scheme",
"vanilla JavaScript for theme switching"
],
"constraints": [
"Use custom properties only for values, not selectors or property names.",
"Keep contrast readable in light and dark modes.",
"Add comments for tokens that product designers may edit."
]
}
CSS pronto para copiar
O segundo argumento em var(--surface, #ffffff) e o fallback. Se --surface nao existir ou tiver um valor invalido, o navegador usa #ffffff. A referencia oficial da MDN sobre var() detalha essa regra.
:root {
color-scheme: light;
/* Palette tokens: raw values */
--blue-50: #eff6ff;
--blue-400: #60a5fa;
--blue-600: #2563eb;
--blue-700: #1d4ed8;
--slate-50: #f8fafc;
--slate-100: #f1f5f9;
--slate-300: #cbd5e1;
--slate-700: #334155;
--slate-900: #0f172a;
--red-600: #dc2626;
/* Semantic theme tokens: values used by the app */
--surface: var(--slate-50);
--surface-raised: #ffffff;
--text: var(--slate-900);
--text-muted: var(--slate-700);
--border: var(--slate-300);
--color-accent: var(--blue-600);
--color-danger: var(--red-600);
/* Typography and spacing */
--font-body: Inter, "Noto Sans", system-ui, sans-serif;
--font-mono: "JetBrains Mono", Consolas, monospace;
--step-0: 1rem;
--step-1: 1.125rem;
--step-2: 1.5rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-6: 1.5rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--shadow-card: 0 12px 30px rgb(15 23 42 / 0.12);
}
[data-theme="dark"] {
color-scheme: dark;
--surface: var(--slate-900);
--surface-raised: #111827;
--text: var(--slate-50);
--text-muted: var(--slate-300);
--border: #334155;
--color-accent: var(--blue-400);
--shadow-card: 0 18px 42px rgb(0 0 0 / 0.35);
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
color-scheme: dark;
--surface: var(--slate-900);
--surface-raised: #111827;
--text: var(--slate-50);
--text-muted: var(--slate-300);
--border: #334155;
--color-accent: var(--blue-400);
}
}
body {
margin: 0;
font-family: var(--font-body, system-ui, sans-serif);
background: var(--surface, #ffffff);
color: var(--text, #111827);
}
.pricing-card {
--card-padding: var(--space-6);
--card-border: var(--border);
max-width: 34rem;
margin: var(--space-6) auto;
padding: var(--card-padding);
background: var(--surface-raised, #ffffff);
border: 1px solid var(--card-border, #d1d5db);
border-radius: var(--radius-lg, 0.75rem);
box-shadow: var(--shadow-card, none);
}
.pricing-card h2 {
margin: 0 0 var(--space-2);
font-size: var(--step-2, 1.5rem);
}
.pricing-card p {
color: var(--text-muted, #4b5563);
line-height: 1.75;
}
.button {
--button-bg: var(--color-accent);
--button-text: #ffffff;
--button-border: transparent;
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 2.75rem;
padding: 0 var(--space-4);
border: 1px solid var(--button-border);
border-radius: var(--radius-md);
background: var(--button-bg, #2563eb);
color: var(--button-text, #ffffff);
font-weight: 700;
cursor: pointer;
}
.button[data-variant="secondary"] {
--button-bg: transparent;
--button-text: var(--color-accent);
--button-border: var(--color-accent);
}
Demo em HTML e JavaScript
O exemplo abaixo nao depende de framework. data-theme guarda a escolha manual, e prefers-color-scheme usa a preferencia do sistema quando nao existe escolha salva.
<section class="pricing-card">
<h2>Claude Code UI Token Demo</h2>
<p>
This card uses CSS custom properties for surface, text, border,
shadow, and button colors.
</p>
<button class="button" type="button" data-theme-toggle>
Toggle theme
</button>
<button class="button" type="button" data-variant="secondary">
Secondary action
</button>
<label>
Accent color
<input type="color" value="#2563eb" data-accent-picker>
</label>
</section>
const root = document.documentElement;
const themeKey = "claude-code-css-variable-theme";
const savedTheme = localStorage.getItem(themeKey);
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
function applyTheme(theme) {
root.setAttribute("data-theme", theme);
localStorage.setItem(themeKey, theme);
}
function toggleTheme() {
const current = root.getAttribute("data-theme") || "light";
applyTheme(current === "dark" ? "light" : "dark");
}
function setAccentColor(color) {
if (CSS.supports("color", color)) {
root.style.setProperty("--color-accent", color);
}
}
applyTheme(savedTheme || (prefersDark ? "dark" : "light"));
document.querySelector("[data-theme-toggle]")?.addEventListener("click", toggleTheme);
document.querySelector("[data-accent-picker]")?.addEventListener("input", (event) => {
setAccentColor(event.target.value);
});
A MDN documenta prefers-color-scheme e color-scheme. Use os dois: um detecta a preferencia do usuario, o outro ajuda o navegador com controles nativos.
Casos de uso
Caso 1: CTAs de artigos e landing pages. Mudar --color-accent permite testar oferta, botao principal ou link do Gumroad sem mexer em todos os seletores.
Caso 2: dashboards SaaS. Tokens compartilhados mantem superficies, bordas, espacamentos e estados de erro consistentes mesmo quando Claude Code gera telas separadas.
Caso 3: white label. Com [data-brand="client-a"], voce sobrescreve apenas tokens semanticos e nao duplica componentes.
Caso 4: acessibilidade. Alto contraste, espaco maior e fontes legiveis podem virar tokens revisados junto com o guia de acessibilidade.
Armadilhas comuns
Nao deixe var() sem fallback em paginas publicas. Prefira color: var(--text, #111827);.
Nomes de propriedades personalizadas diferenciam maiusculas e minusculas. A referencia da MDN sobre custom properties confirma isso; use nomes em minusculas com hifens.
Nao use variaveis CSS em seletores, nomes de propriedades ou condicoes de media query. Elas servem para valores.
Valide atualizacoes por JavaScript. Se uma entrada do usuario chega a setProperty(), confira com CSS.supports().
Revise sombras e bordas no modo escuro. Trocar apenas fundo e texto quase sempre deixa a interface incompleta.
CTA e revisao
Peça uma revisao focada nos tokens:
{
"reviewTarget": "CSS custom properties and theme implementation",
"checks": [
"undefined custom properties without fallback",
"light and dark contrast issues",
"component variants that bypass tokens",
"duplicated raw colors outside :root",
"JavaScript setProperty calls without validation",
"mobile overflow caused by fixed spacing tokens"
],
"output": "List findings with file name, selector, risk, and suggested fix."
}
Para referencia oficial, leia a documentacao do Claude Code. Para acelerar o trabalho diario, comece pela cheatsheet gratuita, use 50 Prompt Templates para prompts reutilizaveis e o Setup Guide para padronizar CLAUDE.md, permissoes, hooks e revisoes de equipe.
Ao testar esse fluxo em cards de CTA, a regra mais util foi manter cores cruas em :root e fazer componentes consumirem tokens semanticos. As mudancas de tema ficaram menores e os diffs do Claude Code ficaram mais faceis de revisar.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Escada de segurança de permissões no Claude Code
Amplie de read-only para edições limitadas, comandos de prova e deploy checks sem perder controle.
Claude Code Small PR Proof Pack: pequenas mudanças fáceis de revisar
Um pacote de prova para PRs do Claude Code: diff, checks, URL pública, CTA e rollback.
Gate de revisão antes do commit com Claude Code
Revisão antes do commit com Claude Code: diff, build, URL pública, Gumroad, consultoria, testes e arquivos fora do escopo.