---
title: "Define every custom property a stylesheet · Agent Wranglers"
url: https://agentwranglers.se/playbook/html-css/naming-and-state/no-undefined-custom-properties
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Define every custom property a stylesheet reads

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Naming and state](https://agentwranglers.se/playbook/html-css/naming-and-state.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- ID: CSS-34
- Level: Recommended
- Chapter: [Naming and state](https://agentwranglers.se/playbook/html-css/naming-and-state)
- Rule: Make every `var(--name)` refer to a custom property that a stylesheet declares. A name that may be missing on purpose gets a fallback inside `var()`.
- How: A misspelt or deleted token does not raise an error. The browser treats the declaration as invalid at computed-value time, and the property falls back to its inherited or initial value. A spacing or colour then quietly disappears on some pages. Collect every declared name from the built CSS and compare it with every name read through `var()`. Token names follow [Prefix a component's custom properties with its name](https://agentwranglers.se/playbook/html-css/naming-and-state/component-custom-properties). Values a script sets with `setProperty`, as in [Write styles only in stylesheets](https://agentwranglers.se/playbook/html-css/structure-and-files/styles-only-in-stylesheets), always carry a fallback.
- Check: A build check over the built CSS finds 0 `var()` calls without a fallback whose name is never declared. Renaming one token in the token file stops the build.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### CSS example

```css
:root { --space-small: 0.5rem; }

/* Passes: declared, or set by a script with a fallback */
.order-card { gap: var(--space-small); }
.order-progress-bar { inline-size: var(--progress, 0%); }

/* Fails: a typo, so the gap silently becomes 0 */
.order-list { gap: var(--space-smal); }
```

### JavaScript example

```js
// Build check: every var() without a fallback reads a declared name
import { readFileSync } from 'node:fs';
const css = readFileSync('dist/main.css', 'utf8');
const declared = new Set([...css.matchAll(/(--[\w-]+)\s*:/g)].map(([, name]) => name));
const missing = [...css.matchAll(/var\(\s*(--[\w-]+)\s*\)/g)].map(([, name]) => name).filter(name => !declared.has(name));
[...new Set(missing)].forEach(name => console.log(`FAIL var(${name}) is never declared`));
process.exit(missing.length ? 1 : 0);
```

### Python example

```python
# The same check in Python
import re, sys
css = open("dist/main.css").read()
declared = set(re.findall(r"(--[\w-]+)\s*:", css))
missing = sorted({name for name in re.findall(r"var\(\s*(--[\w-]+)\s*\)", css) if name not in declared})
for name in missing:
    print(f"FAIL var({name}) is never declared")
sys.exit(1 if missing else 0)
```

## Sources

- [CSS Custom Properties on the guaranteed-invalid value](https://www.w3.org/TR/css-variables-1/#guaranteed-invalid)
- [CSS Custom Properties on using variables](https://www.w3.org/TR/css-variables-1/#using-variables)

## Related rules

- [Prefix a component's custom properties with its name](https://agentwranglers.se/playbook/html-css/naming-and-state/component-custom-properties) in HTML and CSS
- [Write styles only in stylesheets](https://agentwranglers.se/playbook/html-css/structure-and-files/styles-only-in-stylesheets) in HTML and CSS

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/html-css/naming-and-state/no-undefined-custom-properties">Agent Wranglers HTML and CSS playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Prefix a component's custom properties with its name](https://agentwranglers.se/playbook/html-css/naming-and-state/component-custom-properties)
- Next: [Keep script hooks apart from style hooks](https://agentwranglers.se/playbook/html-css/naming-and-state/separate-script-hooks)
- [Naming and state](https://agentwranglers.se/playbook/html-css/naming-and-state)
