Skip to content
tezvyn:

CSS Custom Properties vs JS Theme Object in React

Source: developer.mozilla.orgHardHow cards are made

CSS Custom Properties vs JS Theme Object in React

Tests render overhead vs CSS cascade. Strong answers: CSS variables update styles without re-renders, while JS theme objects in Context force subtree re-renders. Mention scoping, SSR FOUC, and setProperty interop.

What's really being asked

This question evaluates your understanding of the boundary between React's render cycle and the browser's style engine. Interviewers want to see that you know CSS custom properties live outside React state and can be mutated without component re-renders, while JavaScript theme objects distributed via Context inherently couple style changes to React's reconciliation overhead. It also probes your ability to weigh cascade scoping, server-side rendering safety, and runtime interop against type safety and JS logic dependencies.

The full answer

First, render performance. Changing a CSS variable via document.documentElement.style.setProperty or a ref updates the stylesheet and causes only a browser style recalculation, whereas updating a Context value triggers a re-render of the entire consumer subtree. Second, cascade scoping. CSS variables inherit through the DOM, so a parent section can override --bg for its descendants without prop drilling or nested Providers. Third, animation and media query ergonomics. Variables can be transitioned and redefined inside media rules, enabling responsive themes without JS event listeners. Fourth, SSR and hydration. Because variables are declared in static CSS, they avoid hydration mismatches from client-only theme detection, though you must still prevent a flash of unstyled content by setting the correct class or variables before the first paint. Fifth, JS interop. React can still read and write variables imperatively for dynamic effects like theming tied to scroll position or user preference.

The mistakes people make

Claiming that var() can be used inside media query expressions or selectors. MDN explicitly states var() is only valid in property values. Asserting that CSS variables are free of runtime cost; they shift work to the browser's style engine but still require careful SSR handling to avoid FOUC. Suggesting CSS variables should replace every JS theme value even when those values drive layout calculations or conditional rendering in JS. Ignoring that raw CSS variables are untyped strings unless you use the @property at-rule to constrain types and initial values.

What usually comes next

How would you prevent a flash of the wrong theme during server-side rendering? When is a JS theme object still preferable to CSS variables? How does the @property at-rule improve type safety and animation support for custom properties? Can you use CSS variables to define responsive breakpoint values? How do you handle dynamic theme values that must also be read by React for non-style logic?

A concrete example

Imagine a dashboard with a global dark mode toggle. Using Context, flipping the toggle updates a theme state object, causing every themed component to re-render and repaint. Using CSS variables, the toggle instead calls document.documentElement.style.setProperty with --surface and #121212, and also --text and #ffffff. The React tree does not re-render; only the browser recomputes styles. For a scoped override, a Settings panel can set its own --surface on a wrapper div, creating a localized light mode inside a dark app without any React state changes or provider nesting.

Interview question

When updating a global theme in React, why does mutating a CSS custom property avoid subtree re-renders compared to updating a Context theme object?

  • a.CSS custom properties are mutated outside React's state, so only the browser recomputes styles without reconciliation.Correct
  • b.CSS custom properties bypass React's virtual DOM entirely, so themed components never need to reconcile on variable changes.
  • c.CSS custom properties are resolved at build time, eliminating runtime cost that Context theme objects incur during propagation.
  • d.CSS custom properties can be referenced inside media query expressions, enabling responsive themes without JavaScript listeners.
Why?

CSS custom properties live outside React state, so mutating them via setProperty updates the stylesheet without triggering subtree reconciliation. The most tempting distractor claims variables work inside media query expressions, but var() is only valid in property values, not selectors or query expressions.

Just read this? Test yourself on what you have been reading.

Read the original → developer.mozilla.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.

See open roles