CSS Custom Properties (Variables)

📚 Lesson 16 of 30  •  ⏱ 9 min read  •  Intermediate

Declaring & Using Variables

CSS
/* Declare on :root so they're available everywhere */
:root {
  --color-primary: #6c63ff;
  --color-text: #1a1a2e;
  --color-bg: #f8f9fa;
  --font-sans: 'Inter', sans-serif;
  --radius: 8px;
  --shadow: 0 4px 12px rgba(0,0,0,0.1);
}

/* Use with var() */
.btn {
  background: var(--color-primary);
  border-radius: var(--radius);
  font-family: var(--font-sans);
  box-shadow: var(--shadow);
}

/* var() fallback — used if variable isn't defined */
.card { color: var(--color-text, #333); }

Dark Mode with Variables

CSS
:root {
  --bg: #ffffff;
  --text: #1a1a1a;
  --card-bg: #f5f5f5;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f0f0f;
    --text: #e8e8e8;
    --card-bg: #1a1a1a;
  }
}

/* All elements automatically adapt — no other changes needed */
body  { background: var(--bg); color: var(--text); }
.card { background: var(--card-bg); }

Component-scoped Variables

CSS
/* Override variables at component level */
.btn         { --btn-bg: var(--color-primary); }
.btn-danger  { --btn-bg: #e74c3c; }
.btn-success { --btn-bg: #27ae60; }

.btn {
  background: var(--btn-bg);
  /* Three button variants, one rule */
}

Updating Variables with JavaScript

JavaScript
// Change a CSS variable at runtime
document.documentElement.style.setProperty('--color-primary', '#e74c3c');

// Read a CSS variable
const primary = getComputedStyle(document.documentElement)
  .getPropertyValue('--color-primary');

// Theme toggle button
document.querySelector('#theme-btn').addEventListener('click', () => {
  document.body.classList.toggle('dark-theme');
});

Spacing Scale

CSS
:root {
  --space-1: 0.25rem;   /* 4px */
  --space-2: 0.5rem;    /* 8px */
  --space-3: 0.75rem;   /* 12px */
  --space-4: 1rem;      /* 16px */
  --space-6: 1.5rem;    /* 24px */
  --space-8: 2rem;      /* 32px */
  --space-12: 3rem;     /* 48px */
}