← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

CSS Custom Properties (Variables)

frontend CSS3 Beginner
debt(d3/e3/b3/t5)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3). Stylelint (from detection_hints.tools) can detect hard-coded color values and missing custom property usage. The code_pattern explicitly mentions these are detectable: repeated hard-coded colors, no --variable usage.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes defining theme values as custom properties on :root - this is a straightforward pattern replacement across CSS files. Converting hard-coded values to var(--token) is mechanical but touches multiple style declarations, making it slightly more than a one-liner but not a significant refactor.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Custom properties apply to web context only and are frontend-scoped. Once established, they reduce burden by centralizing design tokens. The gravitational pull is moderate - they affect styling decisions but don't define system architecture. They're a design-system enabler that can be adopted incrementally.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception field explicitly states developers confuse CSS custom properties with preprocessor variables (Sass/Less). This is a documented gotcha: preprocessor variables resolve at compile-time producing static CSS, while CSS custom properties are live DOM properties changeable at runtime. Developers familiar with Sass will initially treat them identically and miss the runtime/cascade benefits.

About DEBT scoring →

Also Known As

CSS variables custom properties CSS --variable CSS

TL;DR

Native CSS variables — --primary-color: #4f9cff — that cascade, inherit, and can be updated at runtime via JavaScript.

Explanation

CSS custom properties (declared with -- prefix, accessed with var(--name, fallback)) are live values that participate in the cascade and inherit through the DOM. Unlike preprocessor variables (Sass $var) which are compiled away, custom properties exist at runtime — JavaScript can read and set them: element.style.setProperty('--color', '#f00'). This enables: theme switching without reloading CSS, component-level overrides by redefining variables on a parent, and dynamic animations driven by JS. Scope: variables defined on :root are global; scoped to a selector they only apply within it. Combined with @layer and container queries, custom properties replace many Sass/Less use cases with native browser support.

Common Misconception

CSS custom properties are the same as preprocessor variables (Sass/Less). Preprocessor variables are resolved at compile time and produce static CSS. CSS custom properties are live DOM properties — they can be changed at runtime via JavaScript, inherit through the DOM, and respond to media queries.

Why It Matters

CSS custom properties (variables) enable a single source of truth for design tokens — changing --primary-color in one place updates it everywhere, and they can be modified by JavaScript at runtime.

Common Mistakes

  • Not defining custom properties on :root — they need a global scope to be accessible everywhere.
  • Using preprocessor variables (Sass $variable) when CSS custom properties would allow runtime theming.
  • Not providing fallback values: var(--color, #333) for environments that don't support custom properties.
  • Deeply nested overrides without documentation — the cascade applies to custom properties too.

Code Examples

✗ Vulnerable
/* Magic hex values repeated everywhere — impossible to retheme:
.btn { background: #3b82f6; }
.link { color: #3b82f6; }
.badge { border-color: #3b82f6; }

/* With custom properties — change once, update everywhere: */
:root { --color-primary: #3b82f6; }
.btn { background: var(--color-primary); }
.link { color: var(--color-primary); }
✓ Fixed
:root { --gap: 1rem; --accent: #4f9cff; }
.card { padding: var(--gap); border-color: var(--accent); }
/* Override at component level */
.compact .card { --gap: 0.5rem; }

Added 15 Mar 2026
Edited 22 Mar 2026
Views 33
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 3 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 10 Perplexity 8 SEMrush 3 Google 2 Ahrefs 2 Unknown AI 2
crawler 26 crawler_json 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Define all theme values (colors, spacing, typography) as CSS custom properties on :root — JavaScript can read and write them with getComputedStyle/setProperty for dynamic theming
📦 Applies To
css CSS3 web
🔗 Prerequisites
🔍 Detection Hints
Hard-coded color values repeated across CSS; no --variable usage; theming requiring duplicate CSS rules
Auto-detectable: ✓ Yes stylelint lighthouse
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Low Context: File

✓ schema.org compliant