CSS variables, also called custom properties, let you name important design values such as colors, spacing, shadows, and component sizes. The browser keeps them live, so changing one variable can update many rules instantly.
They are especially helpful for themes and component variants. A card can define its own accent color, a dark theme can override global colors, and a media query can adjust spacing values without rewriting every selector.
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.
/* 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 */
}
Variables follow normal CSS inheritance. A value defined on :root is available everywhere, but a value defined on .pricing-card applies only to that element and its children. This makes them useful for local component customization.
/* 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);
Instead of creating many modifier classes that repeat full declarations, define the parts that change as variables. The component keeps its structure, while each variant changes only the custom properties it owns.
.button {
--button-bg: #2563eb;
--button-text: #ffffff;
--button-border: #2563eb;
background: var(--button-bg);
color: var(--button-text);
border: 1px solid var(--button-border);
padding: 0.75rem 1rem;
border-radius: 0.5rem;
}
.button.secondary {
--button-bg: #ffffff;
--button-text: #2563eb;
}
.button.danger {
--button-bg: #dc2626;
--button-border: #dc2626;
}
.lesson-box:empty::before {
content: "CSS Variables Custom Properties var: add visible content";
}
No. Sass variables are compiled before the browser sees the CSS. CSS variables exist in the browser and can change at runtime.
Yes. JavaScript can call document.documentElement.style.setProperty("--name", value) to update a variable.
You cannot use them as media query conditions, but you can redefine variable values inside a media query.
Explore 500+ free tutorials across 20+ languages and frameworks.