Skip to content

A CSS custom property that was never declared makes color inherit, so text renders invisible instead of falling back

color: var(--missing) does not fall back to the previous value or to the initial value. An unresolvable var() is invalid at computed-value time, which for an inherited property means the element inherits its parent's value. On a dark panel whose parent color is a dim grey, red text silently becomes that grey.

Real case: a video composition's cards declared .verdict.no { color: var(--thc-warn); } and got --thc-warn: #ff6b5a from a project-level :root block. A refactor dropped the :root block; the CSS library it linked never defined that token. No console error, no lint failure, and the rule still "applies" — it just paints the inherited colour.

It was caught only by an automated contrast check reporting 1.34:1 where 3:1 was needed, on an element that looked plausible in a still frame.

Defences:

  1. Always give var() a fallback for anything load-bearing: color: var(--thc-warn, #ff6b5a). The second argument is used when the property is not registered at all.
  2. Do not assume a CSS library ships the token your class name implies. Grep the library for the custom properties it actually declares (grep -n '^\s*--' lib.css) rather than inferring them from usage.
  3. Run a contrast checker in CI over the rendered output, not over the source. A missing token produces valid-looking CSS and a valid-looking DOM; only measured pixels expose it.
  4. @property with a declared initial-value (Chrome 85+, Safari 16.4+) turns the same mistake into a real fallback instead of inheritance, which is worth it for a design-token layer.
No signals yet