Register a CSS custom property with a type so it animates, validates, and inherits the way you want. Without @property, custom properties are always typed as <custom-ident> — meaning a transition between two color values is an instant jump rather than a gradient. Pick a syntax, choose an initial value, and watch the box animate.
| Syntax | Animatable | Example value |
|---|---|---|
<color> | yes | #f0f, oklch(70% 0.2 50) |
<length> | yes | 16px, 2rem, 50vw |
<length-percentage> | yes | 50%, 20px |
<percentage> | yes | 75% |
<number> | yes | 1.5, 0 |
<integer> | yes | 3 |
<angle> | yes | 45deg, 0.5turn |
<time> | yes | 200ms, 1s |
<resolution> | no | 96dpi |
<image> | no | url(bg.png) |
<url> | no | url(/foo) |
<custom-ident> | no | any identifier |
* | no | any value (acts unregistered) |
By default, every CSS variable is parsed as an opaque token. The browser doesn't know --brand: #f00 is a color, so when you write transition: --brand 1s nothing animates — the value flips at the halfway mark like a discrete step. Registering with @property tells the browser the type, lets it interpolate intermediate values, and rejects malformed input by falling back to the initial-value. This unlocks gradient animations (when the gradient stops are custom properties), conic-gradient rotations, scroll-driven property changes, and view-transition-style fades that don't require JavaScript.