USD ($)
$
United States Dollar
Euro Member Countries
India Rupee

CSS Custom Properties (Variables) and Inheritance

Lesson 9/30 | Study Time: 25 Min

CSS custom properties, commonly known as variables, allow developers to define reusable values that can be shared across stylesheets.

Combined with inheritance, they enable consistent styling, easier updates, and more flexible design systems in modern CSS.

Declaring and Using CSS Custom Properties

CSS custom properties store values under custom names, scoped to elements and inherited naturally through the cascade.

Defined with -- syntax, they work in all modern browsers (96%+ global coverage per CanIUse 2025 data). Start simple, then layer complexity.


Basic Syntax and Scope

Custom properties live on any element and cascade down to children, mimicking font-family inheritance but for any value.


1. Declare: --primary-color: #3498db;

2. Use: color: var(--primary-color);

3. Global scope: Root level affects everything

4. Local scope: Component-specific overrides


Quick Example:

css
:root {
--brand-blue: #1e40af;
--spacing-unit: 1rem;
}

.header {
background: var(--brand-blue);
padding: var(--spacing-unit);
}

Fallbacks add resilience: color: var(--color, #000); defaults to black if undefined.

Property Names and Best Practices

Names should be descriptive and namespaced to avoid clashes in team projects.


1. Use kebab-case: --button-bg-primary

2. Namespace by component: --card--padding

3. Avoid CSS keywords: No --color-blue, use --blue-500

CSS Custom Property Naming Best Practices

Pro Tip: Tools like Style Dictionary convert these to JS tokens for React/Vue consistency.

Inheritance and the Cascade in Action

CSS variables inherit like any property, flowing from parent to child unless overridden. This cascading magic powers theme systems without deep nesting.


How Inheritance Works

Variables follow normal CSS rules: specificity, order, and inheritance.



Visual Cascade Example:

text
html (root)
├── --primary: blue (inherits everywhere)
├── body
│ └── --accent: green (body + children)
└── .dark-theme (override)
└── --primary: navy (scoped override)


Debug Trick: Use currentColor keyword: --border: 2px solid currentColor; inherits text color dynamically.


Dynamic Updates with JavaScript

Variables shine with JS—update via element.style.setProperty() for runtime themes.


Theme Toggle Example:

javascript
// Toggle dark mode
document.documentElement.classList.toggle('dark');
/* CSS handles: .dark { --bg: #000; --text: #fff; } */


Advanced: Computed Values

css
--full-width: 100vw;
--sidebar-width: 300px;
--main-width: calc(var(--full-width) - var(--sidebar-width));

Advanced Techniques and Real-World Applications

Move beyond basics to industry patterns like design tokens and CSS-in-JS hybrids.


Theme Switching and Design Systems

Variables enable instant global changes, core to modern design systems.


1. Dark/Light Mode: Single class swap updates 50+ values

2. Brand Colors: --brand-50 to --brand-900 scale

3. Responsive Spacing: --space-mobile: 0.5rem; --space-desktop: 2rem;


Implementation Steps:



Practical Examples:

css
/* Safe fallbacks */
color: var(--text-primary, #333);

/* Math magic */
--aspect-ratio: 16/9;
width: var(--aspect-ratio);

/* Relative to viewport */
--vh-unit: 1vh;
height: calc(var(--vh-unit) * 50);

Performance Note: Browsers optimize var() lookups (under 1ms), faster than JS color parsing.

Common Pitfalls and Debugging

Avoid these traps for production-ready code.


Top Issues


1. Typo mismatch: --primary-color declared, var(--primary) used

2. Specificity wars: Inline styles override :root

3. Unsupported browsers: Rare, but IE11 needs PostCSS polyfill


Debug Steps:


1. DevTools > Computed > Search "var("

2. getComputedStyle(el).getPropertyValue('--var-name')

3. Lighthouse audit flags unused variables