---
title: "Controlling when CSS custom properties are computed"
url: https://daily.dev/posts/controlling-when-css-custom-properties-are-computed-2lphvvmeh
source_url: https://jakearchibald.com/2026/css-custom-property-compute-time
type: article
source: "Jake Archibald"
published: 2026-08-26T14:12:38.274Z
updated: 2026-08-26T15:10:26.335Z
tags: ["webdev", "css"]
reading_time: 4
upvotes: 2
comments: 1
language: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Controlling when CSS custom properties are computed

**[Jake Archibald](https://daily.dev/sources/jakearchibald)** · 4 min read · 2 upvotes · 1 comments

## Summary

CSS custom properties can be computed at different times depending on whether they're registered with @property. Unregistered custom properties default to syntax '*', storing a token stream that gets substituted and evaluated where it's used (e.g. via var()). Registering a property with a concrete syntax like <number> forces it to compute earlier, in the context where it's declared, which changes results for functions like sibling-index(), relative units (em, cqw, etc.), and URL resolution. Arbitrary substitution functions like var(), if(), attr(), and ident() are always substituted immediately regardless of registration, which affects how nested custom properties interact with child overrides.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://jakearchibald.com/2026/css-custom-property-compute-time>

## Questions this post answers

### Does registering a CSS custom property with @property change when its value is computed?

Yes. An unregistered custom property defaults to syntax '*', which stores its value as a token stream computed later, in the context where it's used via var(). Registering it with @property and a concrete syntax like <number> or <url> forces the value to compute earlier, in the context where it's declared, changing results for functions like sibling-index(), relative units, and URL resolution.

_daily.dev surfaces deep CSS platform explainers like this for developers debugging unexpected style computations._

### Why does sibling-index() return a different value depending on whether the custom property storing it is registered?

Unregistered custom properties (syntax '*') keep sibling-index() as a token stream, so it gets substituted into var() and evaluated at the point of use, picking up that element's sibling index. Registering the property with syntax '<number>' computes sibling-index() immediately where the custom property is declared, so var() just substitutes the already-resolved number instead of re-evaluating the function.

_Track subtle CSS spec behaviors like this one on daily.dev before they cause hard-to-debug styling bugs._

### Does var() get substituted before or after a custom property's syntax is applied in CSS?

var() is an arbitrary substitution function, along with if(), attr(), and ident(), and these are substituted immediately regardless of the custom property's registered syntax. This means a child element overriding a variable used inside a parent's calc() expression has no effect, since the parent's value was already substituted before the child's override existed.

_daily.dev helps developers stay current on CSS substitution semantics that affect real-world styling logic._

---

Tags: [#webdev](https://daily.dev/tags/webdev), [#css](https://daily.dev/tags/css)

[View this post on daily.dev](https://daily.dev/posts/controlling-when-css-custom-properties-are-computed-2lphvvmeh)
