DevLab
CSS

CSS Custom Properties (Variables) Explained

Learn how CSS custom properties work, how they differ from preprocessor variables, and how to use them for theming, dark mode, and dynamic styling.

What are CSS Custom Properties?

CSS custom properties (CSS variables) store values in named variables and let you reuse them across your stylesheet. Unlike Sass variables (replaced at compile time), CSS custom properties are live in the browser — changeable by JavaScript, overridable per-element, and responsive to media queries.

Syntax

/* Define on :root to make globally available */
:root {
  --color-primary: #3b82f6;
  --spacing-base: 16px;
  --border-radius: 8px;
}

/* Use with var() — optional fallback after the comma */
.button {
  background-color: var(--color-primary);
  padding: var(--spacing-base);
  color: var(--color-text, #333);  /* #333 if --color-text is unset */
}

Dark Mode Theming

:root {
  --bg: #ffffff;
  --text: #111827;
}

@media (prefers-color-scheme: dark) {
  :root { --bg: #111827; --text: #f9fafb; }
}

/* Or toggle with a class */
[data-theme="dark"] { --bg: #111827; --text: #f9fafb; }

JavaScript Access

// Read
const color = getComputedStyle(document.documentElement)
  .getPropertyValue('--color-primary').trim();

// Write — updates instantly across the whole page
document.documentElement.style.setProperty('--color-primary', '#ef4444');

// Apply saved user preference from localStorage
const saved = localStorage.getItem('accent-color');
if (saved) document.documentElement.style.setProperty('--color-primary', saved);

Component-Scoped Variables

/* Scope to a component */
.card {
  --card-shadow: 0 1px 3px rgba(0,0,0,0.1);
  box-shadow: var(--card-shadow);
}

/* Override for a variant without an extra class */
.card.card--elevated {
  --card-shadow: 0 10px 25px rgba(0,0,0,0.15);
}

CSS Variables vs Sass Variables

Sass $variable is replaced at compile time — the output CSS has just the value. CSS custom properties exist at runtime, so they cascade, inherit, can be overridden per-element, and changed by JavaScript. Use Sass for build-time constants like breakpoints in @media queries (which cannot use CSS variables). Use CSS custom properties for everything that should be themeable or dynamic.

More Learning Topics

RegexRegex Basics: A Complete Beginner's GuideRegexRegex Special Characters: Complete ReferenceRegexRegex Groups and Captures ExplainedRegexRegex Quantifiers: Complete GuideCSSCSS Selectors: The Complete GuideCSSCSS Specificity: Why Your Styles Aren't ApplyingJSONJSONPath Syntax: Query JSON Like XPathTimeUnix Timestamps ExplainedEncodingBase64 Encoding ExplainedEncodingJWT Structure and How It WorksEncodingJWT vs Session Tokens: Which Should You Use?EncodingJWT Refresh Tokens ExplainedCryptoHash Functions Explained: MD5, SHA-256, and When to Use EachEncodingURL Encoding Explained: What %20 Actually MeansJSONJSON Schema Explained: Validate Your JSON DataJSONJSON vs YAML: Which Should You Use?JSONJSON.stringify and JSON.parse: Edge Cases You Should KnowRegexRegex Lookahead and Lookbehind: Match Without ConsumingRegexRegex for Email Validation: The Right ApproachCSSThe CSS Box Model: margin, padding, border, and contentCSSFlexbox vs CSS Grid: When to Use EachTimeISO 8601 Explained: The Right Way to Format DatesTimeUnix Timestamps vs ISO 8601: Which to Use in Your API?EncodingUTF-8 Explained: How Computers Store TextTextCORS Explained: Why Your API Call is BlockedTextHTTP Status Codes: A Practical Developer GuideRegexNamed Capture Groups in Regex: Clean ExtractionsColorsColor Spaces Explained: RGB, HSL, HEX, and BeyondColorsColor Contrast for Developers: WCAG Rules and How to CheckNumbersNumber Bases Explained: Binary, Octal, Decimal, and HexNumbersBitwise Operations for Web DevelopersHTMLHTML Semantic Elements: A Complete ReferenceTextText Encoding for Developers: ASCII, UTF-8, and UnicodeRegexWhat is Regex? Complete Guide for DevelopersJSONJSON Format Explained: Structure, Syntax, and Common ErrorsEncodingHow JWT Works: Header, Payload, Signature DecodedHTMLHow to Convert Any Website to Markdown (for LLMs, RAG & Docs)TextPreparing Website Content for RAG: Clean Markdown Pipelines