CSS variables (officially called custom properties) allow you to store values and reuse them throughout your stylesheet. Instead of repeating the same color, spacing, or font size everywhere, you define it once as a variable and reference it wherever needed. When you update the variable, all uses update automatically. CSS variables make your code more maintainable, enable dynamic theming, and can even be changed with JavaScript for interactive designs.
What Are CSS Variables?
CSS variables are custom properties that store values you can reuse throughout your CSS. They're defined with -- prefix and accessed with var() function.
Why Use CSS Variables?
- Reusability: Define once, use everywhere
- Maintainability: Change one value, update entire site
- Theming: Easy light/dark mode switching
- Dynamic: Can be changed with JavaScript
- Scoped: Different values in different contexts
- Readable: Semantic names instead of raw values
/* Define variables (usually in :root for global access) */
:root {
--primary-color: #667eea;
--secondary-color: #764ba2;
--text-color: #2c3e50;
--spacing-large: 2rem;
--border-radius: 8px;
}
/* Use variables with var() function */
.button {
background: var(--primary-color);
color: white;
padding: var(--spacing-large);
border-radius: var(--border-radius);
}
.card {
border: 2px solid var(--primary-color);
border-radius: var(--border-radius);
}
/* Update variable = everything updates */
:root {
--primary-color: #27ae60; /* All buttons and cards now green */
}Naming Convention: CSS variables must start with -- (two dashes). Use descriptive, kebab-case names like --primary-color or --spacing-large.
Defining CSS Variables
Variables can be defined in any selector, but :root is most common for global variables. The :root selector represents the document root (same as html but with higher specificity).
/* Global variables in :root */
:root {
--primary: #667eea;
--secondary: #764ba2;
--success: #27ae60;
--danger: #e74c3c;
--warning: #f39c12;
/* Spacing scale */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 2rem;
--space-xl: 4rem;
/* Typography */
--font-sans: system-ui, -apple-system, sans-serif;
--font-mono: 'Courier New', monospace;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.25rem;
--font-size-xl: 1.5rem;
}
/* Scoped variables in specific selectors */
.card {
--card-padding: 1.5rem;
--card-bg: white;
padding: var(--card-padding);
background: var(--card-bg);
}
/* Component-specific variables */
.button {
--btn-padding-x: 1.5rem;
--btn-padding-y: 0.75rem;
padding: var(--btn-padding-y) var(--btn-padding-x);
}CSS Variables Example
Using CSS Variables with var()
Access variables using the var() function. You can provide fallback values in case the variable isn't defined.
/* Basic var() usage */
.element {
color: var(--text-color);
background: var(--primary-color);
}
/* Fallback values (used if variable doesn't exist) */
.element {
color: var(--text-color, #333);
/* If --text-color isn't defined, use #333 */
padding: var(--spacing, 1rem);
/* If --spacing isn't defined, use 1rem */
}
/* Multiple fallbacks */
.element {
color: var(--custom-color, var(--primary-color, blue));
/* Try --custom-color, then --primary-color, then blue */
}
/* Using variables in calculations */
.element {
padding: calc(var(--spacing) * 2);
width: calc(100% - var(--sidebar-width));
}
/* Variables in gradients */
.element {
background: linear-gradient(
135deg,
var(--primary-color),
var(--secondary-color)
);
}
/* Variables in shadows */
.element {
box-shadow: 0 4px 6px var(--shadow-color);
}var() with Fallbacks
Variable Scope and Inheritance
CSS variables follow the cascade and inheritance rules. Variables defined in a parent are available to children.
/* Global scope (available everywhere) */
:root {
--global-color: #667eea;
}
/* Parent scope */
.parent {
--parent-color: #27ae60;
}
/* Child inherits parent variables */
.parent .child {
color: var(--parent-color); /* Works! Inherited from parent */
background: var(--global-color); /* Works! From :root */
}
/* Overriding variables */
.parent {
--text-color: blue;
}
.parent .special {
--text-color: red; /* Override for this element and its children */
color: var(--text-color); /* Red, not blue */
}
/* Siblings don't share scoped variables */
.sibling-1 {
--sibling-color: green;
}
.sibling-2 {
color: var(--sibling-color); /* Doesn't work! Not in scope */
}
/* Media query scope */
@media (min-width: 768px) {
:root {
--spacing: 2rem; /* Override for larger screens */
}
}Variable Scope and Inheritance
🎯 Scope Best Practices:
Define global variables in :root for site-wide values like colors and spacing. Define component-specific variables in component selectors. This creates a clear hierarchy and prevents naming conflicts.
Theming with CSS Variables
CSS variables make it easy to create theme systems. Change a few variables to switch between themes instantly.
/* Default (light) theme */
:root {
--bg-primary: white;
--bg-secondary: #f8f9fa;
--text-primary: #2c3e50;
--text-secondary: #7f8c8d;
--border-color: #dee2e6;
--shadow: rgba(0, 0, 0, 0.1);
}
/* Dark theme */
[data-theme="dark"] {
--bg-primary: #1a1a1a;
--bg-secondary: #2d2d2d;
--text-primary: #ffffff;
--text-secondary: #b0b0b0;
--border-color: #404040;
--shadow: rgba(0, 0, 0, 0.3);
}
/* Blue theme */
[data-theme="blue"] {
--bg-primary: #e3f2fd;
--bg-secondary: #bbdefb;
--text-primary: #0d47a1;
--text-secondary: #1976d2;
--border-color: #90caf9;
--shadow: rgba(33, 150, 243, 0.2);
}
/* Apply theme variables */
body {
background: var(--bg-primary);
color: var(--text-primary);
}
.card {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
box-shadow: 0 2px 4px var(--shadow);
}
/* Switch themes with JavaScript */
/* document.documentElement.setAttribute('data-theme', 'dark'); */Theme Switching with CSS Variables
JavaScript Integration
CSS variables can be read and modified with JavaScript, enabling dynamic, interactive designs.
/* Getting CSS variable value */
const root = document.documentElement;
const primaryColor = getComputedStyle(root)
.getPropertyValue('--primary-color');
console.log(primaryColor); // "#667eea"
/* Setting CSS variable value */
root.style.setProperty('--primary-color', '#27ae60');
/* Setting multiple variables */
root.style.setProperty('--primary-color', '#27ae60');
root.style.setProperty('--spacing', '2rem');
root.style.setProperty('--border-radius', '12px');
/* Removing a variable */
root.style.removeProperty('--primary-color');
/* Setting scoped variables */
const card = document.querySelector('.card');
card.style.setProperty('--card-bg', 'lightblue');
/* Dynamic theming */
function setTheme(theme) {
if (theme === 'dark') {
root.style.setProperty('--bg-color', '#1a1a1a');
root.style.setProperty('--text-color', '#ffffff');
} else {
root.style.setProperty('--bg-color', '#ffffff');
root.style.setProperty('--text-color', '#2c3e50');
}
}
/* Interactive slider example */
const slider = document.getElementById('size-slider');
slider.addEventListener('input', (e) => {
root.style.setProperty('--box-size', e.target.value + 'px');
});JavaScript + CSS Variables
Practical CSS Variable Patterns
Color System
/* Define a complete color system */
:root {
/* Brand colors */
--color-primary: #667eea;
--color-secondary: #764ba2;
--color-accent: #f093fb;
/* Semantic colors */
--color-success: #27ae60;
--color-warning: #f39c12;
--color-danger: #e74c3c;
--color-info: #3498db;
/* Neutral colors */
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
/* Text colors */
--text-primary: var(--color-gray-900);
--text-secondary: var(--color-gray-600);
--text-disabled: var(--color-gray-400);
}Spacing Scale
/* Consistent spacing system */
:root {
--space-0: 0;
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-5: 1.25rem; /* 20px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-10: 2.5rem; /* 40px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
--space-20: 5rem; /* 80px */
--space-24: 6rem; /* 96px */
}
/* Use in components */
.card {
padding: var(--space-6);
margin-bottom: var(--space-4);
}
.section {
padding: var(--space-12) var(--space-6);
}Typography System
/* Typography scale */
:root {
/* Font families */
--font-sans: system-ui, -apple-system, sans-serif;
--font-serif: Georgia, serif;
--font-mono: 'Courier New', monospace;
/* Font sizes */
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
--text-5xl: 3rem; /* 48px */
/* Font weights */
--font-light: 300;
--font-normal: 400;
--font-medium: 500;
--font-semibold: 600;
--font-bold: 700;
/* Line heights */
--leading-tight: 1.25;
--leading-normal: 1.5;
--leading-relaxed: 1.75;
}Design System with CSS Variables
Key Takeaways
- CSS variables: Custom properties that store reusable values
- Syntax: Define with
--name, use withvar(--name) - :root: Define global variables in :root selector
- Fallbacks:
var(--name, fallback)for undefined variables - Scope: Variables cascade and can be overridden
- Inheritance: Children inherit parent variables
- Theming: Switch entire themes by changing a few variables
- JavaScript: Read/write variables with getPropertyValue/setProperty
- Use semantic names (--primary-color, not --blue)
- Create systems for colors, spacing, typography
- Variables work in calc(), gradients, shadows
- Browser support: All modern browsers (IE11 not supported)
What's Next?
Congratulations! You've completed the Advanced Styling section covering transforms, transitions, animations, filters, blend modes, and CSS variables. You now have all the tools to create polished, dynamic, maintainable designs.
CSS variables are fundamental to modern CSS architecture. They make your code more maintainable, enable powerful theming systems, and work seamlessly with JavaScript for dynamic interfaces. Start by creating a color and spacing system for your projects—you'll immediately see the benefits when you need to make design changes!
You've now completed 32 comprehensive CSS tutorials covering everything from selectors to advanced styling. You have the knowledge to build beautiful, responsive, animated, and maintainable websites. Keep practicing, experiment with combining techniques, and build amazing things! 🎉