CSS Variables Explained
Understand CSS custom properties, inheritance, scope and practical techniques for building reusable and maintainable styles.
CSS Variables, officially called CSS Custom Properties, allow developers to store reusable values directly inside CSS. Instead of repeating colors, spacing values or font sizes throughout a stylesheet, a single variable can be defined once and referenced wherever it is needed.
They have become a fundamental part of modern frontend development because they simplify maintenance, improve consistency and make dynamic themes much easier to implement without preprocessors.
What Are CSS Variables?
A CSS variable stores a value that can later be reused with the var() function. Variables can contain colors, lengths, font families, shadows, gradients and many other valid CSS values.
:root {
--primary-color: #2563eb;
}
.button {
background: var(--primary-color);
}Whenever the value of --primary-color changes, every declaration that references it automatically updates.
Why Use CSS Variables?
Before custom properties existed, developers often repeated the same values hundreds of times or relied on CSS preprocessors such as Sass. Native CSS variables eliminate much of that repetition while remaining fully dynamic in the browser.
- Reduce duplicated values.
- Keep designs consistent.
- Simplify maintenance.
- Support runtime theme switching.
- Improve readability.
- Work without preprocessors.
Variable Syntax
Every custom property begins with two hyphens and is referenced through the var() function.
:root {
--spacing: 24px;
}
.card {
padding: var(--spacing);
}The browser substitutes the stored value wherever var(--spacing) appears.
Why :root Is Commonly Used
Most projects declare global variables inside the :root selector because it represents the highest element in the document tree. Variables defined there are available throughout the entire page unless overridden.
:root {
--background: #ffffff;
--text: #1f2937;
--border-radius: 12px;
}This approach creates a centralized design system that every component can share.
Local Variables
Variables do not have to be global. They can also be declared inside individual selectors where only that element and its descendants should access them.
.card {
--card-padding: 20px;
padding: var(--card-padding);
}Local variables help isolate component-specific values while avoiding unnecessary global declarations.
Variable Scope
| Location | Availability |
|---|---|
| :root | Entire document |
| .component | Component and children |
| .button | Button and descendants |
| Inline style | Single element |
Inheritance
One powerful feature of CSS variables is inheritance. Child elements automatically receive custom properties defined by their ancestors unless they define new values themselves.
.container {
--text-color: #374151;
}
.container p {
color: var(--text-color);
}The paragraph automatically inherits the custom property from its parent container.
Overriding Variables
A child element can redefine an inherited variable without affecting the original declaration.
:root {
--primary: #2563eb;
}
.dark {
--primary: #60a5fa;
}
.button {
background: var(--primary);
}Buttons inside the .dark container automatically use the new value while the rest of the page keeps the original color.
Fallback Values
The var() function can provide a fallback value when a custom property has not been defined.
color: var(--link-color, #2563eb);If --link-color does not exist, the browser simply uses #2563eb instead.
Building Design Systems
CSS variables are one of the foundations of modern design systems. Instead of hardcoding colors and spacing into every component, teams define reusable design tokens that represent the visual language of an application.
:root {
--color-primary: #2563eb;
--color-danger: #dc2626;
--space-sm: 8px;
--space-md: 16px;
--space-lg: 24px;
--radius-md: 12px;
}Components then reference these variables instead of fixed values, making the entire interface easier to update and maintain.
Dark Mode with CSS Variables
One of the most popular applications of CSS variables is implementing dark mode. Rather than duplicating every rule, developers simply redefine the variables for dark themes while keeping component styles unchanged.
:root {
--bg: #ffffff;
--text: #111827;
}
.dark {
--bg: #111827;
--text: #f9fafb;
}
body {
background: var(--bg);
color: var(--text);
}Switching between themes becomes as simple as adding or removing a single class from the page.
Variables Inside Calculations
Custom properties work seamlessly with CSS functions such as calc(), clamp(), min() and max(). This makes responsive layouts much more flexible.
:root {
--spacing: 16px;
}
.container {
padding: calc(var(--spacing) * 2);
}Combining variables with CSS functions allows complex values to remain readable and easy to adjust.
Variables Can Store More Than Colors
Although colors are the most common use case, custom properties can represent nearly any CSS value.
| Variable | Example Value |
|---|---|
| Colors | #2563eb |
| Spacing | 24px |
| Border radius | 12px |
| Font family | Inter, sans-serif |
| Animation duration | 250ms |
| Shadow | 0 8px 24px rgba(0,0,0,.15) |
Naming Conventions
Clear naming improves maintainability. Variable names should describe their purpose rather than their current appearance whenever possible.
| Less Flexible | Preferred |
|---|---|
| --blue | --primary-color |
| --red | --error-color |
| --16px | --spacing-md |
| --round | --border-radius |
| --gray1 | --text-secondary |
Performance
CSS variables are implemented natively by browsers and are highly efficient. Updating a custom property automatically updates all declarations that depend on it without requiring developers to rewrite individual rules.
Common Mistakes
- Using unclear variable names.
- Creating too many unnecessary global variables.
- Mixing component-specific variables with global design tokens.
- Hardcoding values instead of reusing existing variables.
- Forgetting to define fallback values when appropriate.
CSS Variables vs Sass Variables
CSS variables are sometimes confused with Sass variables, but they work very differently. Sass variables exist only during compilation, while CSS variables remain available in the browser after the stylesheet has loaded.
| CSS Variables | Sass Variables |
|---|---|
| Available at runtime | Compile-time only |
| Can be modified with JavaScript | Cannot change after compilation |
| Inherited by default | No inheritance |
| Work directly in browsers | Require preprocessing |
Browser Support
CSS Custom Properties are supported by all modern browsers, making them suitable for virtually every new web project. Legacy browsers such as Internet Explorer do not support them, but these browsers are no longer relevant for most applications.
Real-World Examples
Most modern websites use CSS variables extensively. Design systems, UI frameworks and component libraries rely on them to centralize colors, typography, spacing and theme configuration while keeping components reusable.
- Application themes.
- Dark and light modes.
- Brand color management.
- Typography systems.
- Spacing scales.
- Component libraries.
When to Use CSS Variables
| Good Use Cases | Less Suitable Cases |
|---|---|
| Theme colors | One-time values |
| Spacing systems | Temporary experiments |
| Typography scales | Values used once |
| Shared component styles | Completely static CSS |
| Responsive design tokens | Unused declarations |
Best Practices
- Keep global variables inside :root.
- Use meaningful names based on purpose instead of appearance.
- Group variables by category such as colors, spacing and typography.
- Override variables locally only when component customization is required.
- Use fallback values when variables may be undefined.
- Avoid creating unnecessary variables for single-use values.
Frequently Asked Questions
What are CSS variables?
CSS variables are custom properties that store reusable CSS values which can be referenced with the var() function.
Can CSS variables be changed with JavaScript?
Yes. JavaScript can modify CSS custom properties at runtime, making them ideal for theme switching and interactive interfaces.
Do CSS variables inherit?
Yes. Custom properties inherit naturally through the DOM unless they are overridden by descendant elements.
Can CSS variables store numbers or only colors?
They can store almost any valid CSS value, including colors, lengths, fonts, gradients, shadows and timing values.
Should I still use Sass variables?
Yes, if your project already uses Sass. Sass variables and CSS variables solve different problems and are often used together.
Helpful CSS Variable Tools
A CSS Variable Generator helps create reusable custom properties, a CSS Variable Extractor finds repeated values that can become variables, a CSS Formatter keeps large stylesheets readable, a CSS Minifier optimizes production CSS, and a Color Converter simplifies working with HEX, RGB, HSL and other color formats while building design systems.
Conclusion
CSS variables have transformed the way modern stylesheets are written. They make interfaces easier to maintain, simplify responsive design, enable powerful theming capabilities and reduce duplicated code. Whether you're building a small landing page or a large design system, understanding CSS custom properties is an essential skill that leads to cleaner, more scalable and more maintainable CSS.