CSS Variables (Custom Properties)
What are CSS Variables?
CSS Variables (officially called Custom Properties) let you store values that can be reused throughout your stylesheet. They are defined with --name and accessed with var(--name). Unlike preprocessor variables (Sass, Less), CSS variables are live — they can be changed at runtime with JavaScript and respond to media queries.
- Defined with
--prefix:--primary-color: #3498db; - Used with
var():color: var(--primary-color); - Scoped to the element where they're defined (and its descendants)
- Can have fallback values:
var(--color, blue)
/* Define variables in :root — available globally */
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--danger-color: #e74c3c;
--text-color: #2c3e50;
--bg-color: #ecf0f1;
--font-main: 'Roboto', sans-serif;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--border-radius: 4px;
--transition-speed: 0.3s;
}
/* Use variables with var() */
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: var(--font-main);
}
.btn-primary {
background-color: var(--primary-color);
padding: var(--spacing-md);
border-radius: var(--border-radius);
transition: all var(--transition-speed);
}
.btn-primary:hover {
background-color: var(--secondary-color);
}
/* Fallback value — used if variable is not defined */
.card {
border: 1px solid var(--border-color, #ddd);
}
/* Scoped variables — override in specific contexts */
.dark-theme {
--bg-color: #1a1a2e;
--text-color: #eee;
--primary-color: #64b5f6;
}
/* Calculations with variables */
.container {
padding: calc(var(--spacing-md) * 2); /* 32px */
margin-top: calc(var(--spacing-lg) + 10px); /* 34px */
}
Dynamic Theming with CSS Variables
/* Light theme (default) */
:root {
--bg: #ffffff;
--text: #2c3e50;
--card-bg: #f8f9fa;
--border: #dee2e6;
}
/* Dark theme — override variables */
[data-theme="dark"] {
--bg: #1a1a2e;
--text: #eee;
--card-bg: #16213e;
--border: #0f3460;
}
/* Use variables everywhere */
body {
background-color: var(--bg);
color: var(--text);
transition: background-color 0.3s, color 0.3s;
}
.card {
background-color: var(--card-bg);
border: 1px solid var(--border);
}
// Toggle theme
const toggleBtn = document.getElementById('theme-toggle');
toggleBtn.addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
});
// Load saved theme
const saved = localStorage.getItem('theme');
if (saved) document.documentElement.setAttribute('data-theme', saved);