CSS Variables dengan Claude Code: token tema praktis
Gunakan Claude Code untuk CSS variables, var(), token tema, dark mode, dan review UI yang aman.
CSS variables membuat gaya lebih mudah dirawat
CSS variables, atau nama resminya CSS custom properties, memungkinkan kita membuat nilai seperti --color-accent lalu memakainya dengan var(--color-accent). Sederhananya, ini adalah tempat penyimpanan bernama untuk warna, spacing, radius, shadow, ukuran font, dan variasi state.
Saat memakai Claude Code, lapisan ini sangat membantu. Jika prompt hanya berbunyi “buat card yang bagus”, hasil CSS bisa berisi warna hard-code di banyak selector. Jika prompt meminta theme tokens terlebih dahulu, perubahan berikutnya menjadi lebih kecil: dark mode, warna CTA, brand klien, dan state error cukup mengganti token.
Baca juga implementasi dark mode, design system, dan pola Flexbox. Modelnya: palette tokens menyimpan nilai mentah, semantic tokens menjelaskan arti produk, component tokens mengatur satu bagian UI, dan state tokens menimpa nilai untuk dark, danger, compact, atau brand.
Minta token sebelum minta komponen
Prompt berikut membuat Claude Code menghasilkan dasar yang bisa dipakai ulang, bukan hanya CSS sekali pakai.
{
"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 yang bisa langsung dicopy
Argumen kedua di var(--surface, #ffffff) adalah fallback. Jika --surface belum ada atau tidak valid, browser memakai #ffffff. Referensi resmi MDN tentang var() menjelaskan aturan ini.
: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 HTML dan JavaScript
Contoh ini berjalan tanpa framework. data-theme menyimpan pilihan manual, sedangkan prefers-color-scheme mengikuti preferensi sistem saat belum ada pilihan.
<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);
});
MDN menjelaskan prefers-color-scheme dan color-scheme. Gunakan keduanya: satu membaca preferensi pengguna, satu membantu browser memilih warna native control.
Use case praktis
Use case 1: CTA artikel dan landing page. Mengubah --color-accent cukup untuk menguji warna tombol utama, penawaran, atau link Gumroad.
Use case 2: dashboard SaaS. Token bersama menjaga surface, border, spacing, dan error state tetap konsisten walau Claude Code membuat layar di sesi berbeda.
Use case 3: white-label branding. Dengan [data-brand="client-a"], kamu hanya menimpa semantic tokens tanpa menggandakan komponen.
Use case 4: aksesibilitas. Kontras tinggi, spacing lebih besar, dan ukuran teks yang lebih nyaman bisa menjadi token yang direview bersama panduan aksesibilitas.
Jebakan yang sering terjadi
Jangan memakai var() tanpa fallback di halaman publik. Gunakan color: var(--text, #111827);.
Nama custom property peka huruf besar-kecil. Referensi MDN tentang custom properties menegaskan hal ini; pakai huruf kecil dan tanda hubung.
Jangan gunakan CSS variables untuk selector, nama property, atau kondisi media query. Gunakan untuk nilai.
Validasi update dari JavaScript. Jika input pengguna masuk ke setProperty(), periksa dengan CSS.supports().
Review shadow dan border di dark mode. Mengganti background dan teks saja biasanya belum cukup.
CTA dan review
Minta Claude Code melakukan review khusus pada token:
{
"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."
}
Untuk referensi resmi, baca dokumentasi Claude Code. Untuk kerja harian, mulai dari cheatsheet gratis, gunakan 50 Prompt Templates jika butuh prompt review yang siap pakai, dan gunakan Setup Guide untuk merapikan CLAUDE.md, permission, hooks, dan review tim.
Saat mencoba alur ini pada card CTA, aturan paling berguna adalah menyimpan warna mentah di :root dan membuat komponen memakai semantic tokens. Perubahan tema jadi lebih kecil dan diff dari Claude Code lebih mudah dipercaya.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission safety ladder Claude Code: perluas akses tanpa kehilangan kontrol
Naik dari read-only ke edit terbatas, command bukti, dan cek deploy dengan kontrol yang jelas.
Claude Code Small PR Proof Pack: perubahan kecil yang mudah direview
Paket bukti untuk PR Claude Code: diff, check, URL publik, jalur CTA, dan rollback.
Review gate Claude Code sebelum commit: diff, test, URL publik, dan CTA
Cara memakai Claude Code sebelum commit: diff scope, build, URL publik, link Gumroad, CTA konsultasi, missing test, dan file tidak terkait.