CSS Variables: Unleashing the Power of Custom Properties
Learn how to use CSS custom properties (variables) to create maintainable, themeable stylesheets with dynamic behavior.
Introduction to CSS Variables
CSS Variables, officially known as CSS Custom Properties, are entities defined by developers that contain specific values to be reused throughout a document. They help create more maintainable and dynamic stylesheets by centralizing values that might change.
Basic Syntax
Defining and using CSS variables is straightforward:
:root {
--primary-color: #3490dc;
--secondary-color: #ffed4a;
--danger-color: #e3342f;
--success-color: #38c172;
--font-size-base: 16px;
--line-height: 1.5;
}
button {
background-color: var(--primary-color);
color: white;
font-size: var(--font-size-base);
line-height: var(--line-height);
}
Scope and Inheritance
CSS variables follow the standard cascade and inherit from parent elements:
:root {
--main-color: blue;
}
.container {
--main-color: red;
}
/* This will be blue */
p {
color: var(--main-color);
}
/* This will be red */
.container p {
color: var(--main-color);
}
Fallback Values
You can provide fallback values for variables that might not be defined:
.element {
color: var(--text-color, black);
}
Using Variables in Calculations
CSS Variables work well with calc()
for dynamic calculations:
:root {
--spacing-unit: 8px;
}
.card {
padding: var(--spacing-unit);
margin-bottom: calc(var(--spacing-unit) * 2);
}
.card-large {
padding: calc(var(--spacing-unit) * 2);
}
Theming with CSS Variables
One of the most powerful applications is creating themeable interfaces:
:root {
/* Light theme (default) */
--bg-color: white;
--text-color: #333;
--border-color: #ddd;
}
.dark-theme {
--bg-color: #121212;
--text-color: #f1f1f1;
--border-color: #444;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
}
.card {
border: 1px solid var(--border-color);
}
Now you can toggle themes by simply adding or removing the dark-theme
class from a parent element.
Responsive Design with CSS Variables
CSS variables can adapt to different viewport sizes using media queries:
:root {
--container-width: 1200px;
--font-size-heading: 32px;
}
@media (max-width: 768px) {
:root {
--container-width: 100%;
--font-size-heading: 24px;
}
}
.container {
width: var(--container-width);
}
h1 {
font-size: var(--font-size-heading);
}
Manipulating Variables with JavaScript
A major advantage of CSS variables is that they can be manipulated with JavaScript:
// Getting a CSS variable value
const rootStyles = getComputedStyle(document.documentElement);
const primaryColor = rootStyles.getPropertyValue('--primary-color').trim();
console.log(primaryColor); // #3490dc
// Setting a CSS variable value
document.documentElement.style.setProperty('--primary-color', '#7e3af2');
This allows for dynamic theming, user preferences, and interactive elements.
Organizing CSS Variables
For larger projects, organizing variables helps maintain clarity:
:root {
/* Colors */
--color-primary: #3490dc;
--color-secondary: #ffed4a;
--color-success: #38c172;
--color-danger: #e3342f;
--color-warning: #f6993f;
--color-info: #6574cd;
/* Typography */
--font-family-sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
--font-family-mono: 'Fira Code', monospace;
--font-size-xs: 12px;
--font-size-sm: 14px;
--font-size-md: 16px;
--font-size-lg: 18px;
--font-size-xl: 20px;
/* Spacing */
--spacing-1: 4px;
--spacing-2: 8px;
--spacing-3: 16px;
--spacing-4: 24px;
--spacing-5: 32px;
--spacing-6: 48px;
/* Borders */
--border-radius-sm: 2px;
--border-radius-md: 4px;
--border-radius-lg: 8px;
--border-width: 1px;
}
Browser Support
CSS Variables are supported in all modern browsers. For legacy support, you can use a fallback approach:
.button {
/* Fallback for older browsers */
background-color: #3490dc;
/* Modern browsers will use this */
background-color: var(--primary-color, #3490dc);
}
Practical Example: Component Library
Here’s how CSS variables can power a component library:
:root {
/* Base variables */
--color-primary: #4299e1;
--color-primary-dark: #3182ce;
--color-white: #ffffff;
--border-radius: 4px;
--transition-speed: 0.2s;
/* Component-specific variables */
--button-padding-x: 16px;
--button-padding-y: 8px;
--input-border-color: #e2e8f0;
--input-focus-ring-color: rgba(66, 153, 225, 0.5);
}
.btn {
display: inline-block;
padding: var(--button-padding-y) var(--button-padding-x);
background-color: var(--color-primary);
color: var(--color-white);
border-radius: var(--border-radius);
transition: background-color var(--transition-speed) ease;
}
.btn:hover {
background-color: var(--color-primary-dark);
}
.input {
border: 1px solid var(--input-border-color);
border-radius: var(--border-radius);
padding: var(--button-padding-y) var(--button-padding-x);
transition: box-shadow var(--transition-speed) ease;
}
.input:focus {
box-shadow: 0 0 0 3px var(--input-focus-ring-color);
outline: none;
}
Conclusion
CSS Variables have transformed how we write and maintain CSS. They provide a native way to create dynamic, maintainable, and theme-able stylesheets without preprocessors. By centralizing values, enabling runtime manipulation, and following the cascade, CSS Variables help create more robust and flexible styling systems.