CSS Custom Properties (Variables): Complete Guide
Hey there, CSS explorer! 👋 Ready to make your stylesheets more dynamic and maintainable? Today, we’re diving into CSS Custom Properties (also known as CSS Variables). Get ready to write smarter, more flexible CSS that’s a joy to maintain!
What Are CSS Custom Properties?
Think of CSS Custom Properties as variables you can use throughout your stylesheets. They start with --
and are accessed using the var()
function. Here’s a simple example:
:root {
--primary-color: #3498db;
--spacing-unit: 1rem;
--border-radius: 4px;
}
.button {
background-color: var(--primary-color);
padding: var(--spacing-unit);
border-radius: var(--border-radius);
}
Why Use Custom Properties?
- Easy Theme Switching
- More Maintainable Code
- Dynamic Changes with JavaScript
- Contextual Values
Basic Syntax and Usage
Declaring Custom Properties
/* Global scope */
:root {
--main-color: #333;
--header-height: 60px;
--content-width: 1200px;
}
/* Local scope */
.card {
--card-padding: 1.5rem;
--card-bg: #f8f9fa;
}
Using Custom Properties
.element {
/* Basic usage */
color: var(--main-color);
/* With fallback value */
padding: var(--element-padding, 1rem);
/* Multiple variables */
margin: var(--spacing-y) var(--spacing-x);
}
Real-World Example: Theme System
/* Define theme variables */
:root {
/* Colors */
--color-primary: #3498db;
--color-secondary: #2ecc71;
--color-text: #333;
--color-background: #fff;
/* Typography */
--font-size-base: 16px;
--font-size-h1: 2.5rem;
--font-size-h2: 2rem;
--font-family-main: 'Arial', sans-serif;
/* Spacing */
--spacing-small: 0.5rem;
--spacing-medium: 1rem;
--spacing-large: 2rem;
/* Layout */
--container-width: 1200px;
--border-radius: 4px;
}
/* Dark theme */
[data-theme="dark"] {
--color-primary: #5dade2;
--color-secondary: #52be80;
--color-text: #f5f5f5;
--color-background: #1a1a1a;
}
/* Using the variables */
body {
font-family: var(--font-family-main);
font-size: var(--font-size-base);
color: var(--color-text);
background-color: var(--color-background);
}
.container {
max-width: var(--container-width);
padding: var(--spacing-medium);
margin: 0 auto;
}
.button {
background-color: var(--color-primary);
padding: var(--spacing-small) var(--spacing-medium);
border-radius: var(--border-radius);
color: white;
}
Advanced Techniques
1. Calculated Values
:root {
--spacing-unit: 8px;
}
.element {
/* Using calc() with custom properties */
padding: calc(var(--spacing-unit) * 2);
margin-bottom: calc(var(--spacing-unit) * 4);
}
2. Complex Values
:root {
--shadow-color: rgba(0, 0, 0, 0.1);
--shadow-offset: 0 2px 4px;
}
.card {
/* Combining multiple values */
box-shadow: var(--shadow-offset) var(--shadow-color);
}
3. Responsive Values
:root {
--content-padding: 1rem;
}
@media (min-width: 768px) {
:root {
--content-padding: 2rem;
}
}
.content {
padding: var(--content-padding);
}
Working with JavaScript
Reading Custom Properties
// Get the value of a custom property
const rootStyles = getComputedStyle(document.documentElement);
const primaryColor = rootStyles.getPropertyValue('--primary-color');
Setting Custom Properties
// Set a custom property value
document.documentElement.style.setProperty('--primary-color', '#ff0000');
Theme Switching Example
/* Theme definitions */
:root {
/* Light theme (default) */
--color-bg: #ffffff;
--color-text: #333333;
--color-primary: #3498db;
--color-secondary: #2ecc71;
--color-accent: #e74c3c;
}
[data-theme="dark"] {
--color-bg: #1a1a1a;
--color-text: #f5f5f5;
--color-primary: #5dade2;
--color-secondary: #52be80;
--color-accent: #ef5350;
}
// Theme toggle function
function toggleTheme() {
const root = document.documentElement;
const currentTheme = root.getAttribute('data-theme');
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
root.setAttribute('data-theme', newTheme);
}
Component-Based Architecture
/* Component variables */
.card {
--card-padding: var(--spacing-medium);
--card-bg: var(--color-background);
--card-border: 1px solid rgba(0, 0, 0, 0.1);
padding: var(--card-padding);
background: var(--card-bg);
border: var(--card-border);
}
/* Component variants */
.card--compact {
--card-padding: var(--spacing-small);
}
.card--featured {
--card-bg: var(--color-primary);
--card-border: none;
}
Best Practices
- Naming Conventions
/* Use meaningful, structured names */
:root {
--color-primary-100: #ebf5fb;
--color-primary-500: #3498db;
--color-primary-900: #1a5276;
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
--spacing-xl: 4rem;
}
- Organization
:root {
/* Colors */
--color-brand: #3498db;
--color-text: #333;
/* Typography */
--font-size-base: 16px;
--line-height: 1.5;
/* Layout */
--container-width: 1200px;
--grid-gap: 2rem;
/* Animation */
--transition-fast: 0.2s;
--transition-slow: 0.5s;
}
- Scoping
/* Global variables */
:root {
--spacing-unit: 8px;
}
/* Component-specific variables */
.modal {
--modal-width: 600px;
--modal-padding: calc(var(--spacing-unit) * 3);
}
Practice Exercise: Create a Button System
Try creating this flexible button system:
:root {
/* Base variables */
--button-padding-y: 0.5rem;
--button-padding-x: 1rem;
--button-border-radius: 4px;
--button-transition: all 0.3s ease;
/* Color variations */
--button-primary-bg: #3498db;
--button-success-bg: #2ecc71;
--button-danger-bg: #e74c3c;
}
.button {
padding: var(--button-padding-y) var(--button-padding-x);
border-radius: var(--button-border-radius);
transition: var(--button-transition);
border: none;
color: white;
}
.button--primary {
background-color: var(--button-primary-bg);
}
.button--success {
background-color: var(--button-success-bg);
}
.button--danger {
background-color: var(--button-danger-bg);
}
/* Hover states */
.button:hover {
filter: brightness(1.1);
transform: translateY(-1px);
}
What’s Next?
Now that you’ve mastered CSS Custom Properties, you can explore:
- CSS Modules and CSS-in-JS
- Advanced Theming Systems
- Dynamic Color Schemes
- Component Libraries
Remember, CSS Custom Properties are incredibly powerful, but with great power comes great responsibility! Keep your naming consistent, document your variables, and think about scoping. Your future self (and your team) will thank you!
Got questions about CSS Custom Properties? Drop them in the comments below! Happy coding!