CSS Custom Properties
CSSWithout @property, the browser treats custom properties as opaque strings — they can't be interpolated. Registering a property with a syntax type unlocks smooth transitions between values.
The browser cannot interpolate the background shorthand — it jumps between keyframes with no smooth transition.
--hue-start is a registered <number> — the browser interpolates it like any numeric value.
@property --hue-start {
syntax: '<number>';
inherits: false;
initial-value: 220;
}
concepts
The browser treats --hue: 220 as an opaque string. It can't interpolate "220" → "580" — so animating it causes a jump rather than a smooth transition.
Declares a syntax type for a custom property, giving the browser the type information it needs to interpolate values just like built-in CSS properties.
Prevents the property from cascading down to child elements, avoiding unexpected color inheritance from ancestor elements that also use the property.
Gradient colors use hsl(var(--hue), ...). When --hue is a registered <number>, the browser smoothly tweens the number — the gradient color changes as a side effect.
core pattern
@property --hue {
syntax: '<number>'; /* typed — browser can interpolate */
inherits: false;
initial-value: 220;
}
@keyframes spin {
from { --hue: 220; }
to { --hue: 580; } /* browser interpolates 220→580 */
}
.box {
background: linear-gradient(135deg,
hsl(var(--hue), 80%, 60%),
hsl(calc(var(--hue) + 120), 80%, 60%)
);
animation: spin 2s ease-in-out infinite alternate;
}