A gradient angle that actually animates
CaveatCustom properties are strings until you register them. Animate an unregistered --angle and it jumps from start to end with nothing in between — no error, no warning, just a hard cut at 50%.
FallbackRegistering it declares a type, so the browser can interpolate. It also gives the property an initial value, which is what stops the first frame from rendering unstyled.
@property --spin {
syntax: "<angle>"; /* now it can interpolate */
inherits: false;
initial-value: 0deg;
}
.ring {
background: conic-gradient(from var(--spin), …);
}
@keyframes spin { to { --spin: 360deg; } }
Published
Questions
Why can't I transition from one linear-gradient to another?
background-image animates discretely, so the browser swaps one gradient for the other in a single step. Move the part that changes (an angle, a colour stop, a position) into a registered custom property and animate that property; the gradient is recomputed on every frame.
Why is my @property rule being ignored?
The rule is dropped as invalid when a required descriptor is missing. syntax and inherits are always required, and initial-value is required for any syntax other than "*". Without the registration the property is a plain string again and snaps at 50%.
Why does a child element not see the animated custom property?
With inherits: false, descendants do not receive the value you set on the parent and fall back to initial-value, so the child sits at 0deg. Animate the property on the element that reads it, or register it with inherits: true.