DEV3 Technologies home

DEV3 Developer Forum

How do CSS custom properties (variables) work for theming, and how do they differ from Sass variables?

dev3 ·

I want to support light, dark and a brand theme without compiling separate stylesheets. Do CSS variables cascade and can JavaScript change them at runtime?

#css#custom-properties#theming

0

1 reply

dev3 · Accepted answer

Custom properties are live and cascade

Sass variables are replaced at build time. CSS custom properties exist in the browser, inherit down the DOM, and can be changed at runtime or scoped to any element.

:root {
  --bg: #ffffff;
  --fg: #111827;
  --accent: #2563eb;
  --radius: 0.5rem;
}

[data-theme="dark"] {
  --bg: #0b0f19;
  --fg: #e5e7eb;
  --accent: #60a5fa;
}

body { background: var(--bg); color: var(--fg); }
.btn { background: var(--accent); border-radius: var(--radius); }

Switching theme means changing one attribute: document.documentElement.dataset.theme = 'dark'. Every use updates instantly, with no re-render of your JS framework.

Fallbacks and scoping

.card { padding: var(--card-pad, 1rem); }   /* default when undefined */
.card.compact { --card-pad: 0.5rem; }       /* local override */

Update from JavaScript

el.style.setProperty('--progress', '0.4');
const v = getComputedStyle(el).getPropertyValue('--accent');

This is ideal for pointer-follow effects and progress bars (width: calc(var(--progress) * 100%)).

Typed, animatable variables

Plain variables are strings, so they cannot be transitioned. Register them:

@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
.spinner { background: conic-gradient(from var(--angle), red, blue); animation: spin 2s linear infinite; }
@keyframes spin { to { --angle: 360deg; } }

Pitfalls

  • A variable set to an invalid value for its use makes the declaration "invalid at computed-value time" and falls back to inherited or initial value; check DevTools.
  • Variables cannot be used in media query conditions; use container or media queries with literal values.
  • Tailwind 4 exposes its theme as variables (var(--color-blue-500)), so you can mix both approaches.
0

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.