@property
Animatable Custom Properties
A plain custom property is just text to the browser. It has no idea whether --angle holds an angle, a color or a length, so it can’t blend between two values. @property gives it a type, and a transition on that property finally works.
Typed --angle-typed
Plain --angle-plain
Typed --tint-typed
Plain --tint-plain
The CSS
/* @property registers a property NAME page-wide, so each typed/plain pair
below needs two different custom properties, not two uses of one. */
@property --angle-typed {
syntax: '<angle>';
inherits: false;
initial-value: 0deg;
}
.dial-typed {
--angle-typed: 0deg;
background: conic-gradient(from var(--angle-typed), var(--accent), var(--accent-tertiary));
transition: --angle-typed 0.6s; /* eases: --angle-typed has a registered <angle> type */
}
/* Same idea, typed as a <color> instead of an <angle>. */
@property --tint-typed {
syntax: '<color>';
inherits: false;
initial-value: #F0748A;
}
.swatch-typed {
--tint-typed: #F0748A;
background: var(--tint-typed);
transition: --tint-typed 0.6s; /* blends smoothly between two colors */
}
/* And as a <percentage>, driving a width. */
@property --fill-typed {
syntax: '<percentage>';
inherits: false;
initial-value: 0%;
}
.bar-typed {
--fill-typed: 0%;
width: var(--fill-typed);
transition: --fill-typed 0.6s; /* grows/shrinks instead of jumping */
}
/* Every "-plain" counterpart above uses the identical CSS with an
unregistered property name, so none of it interpolates. */How it works
Each row runs the same experiment with a different type: an <angle> for the dial, a <color> for the swatch, a <percentage> for the bar. The left one is registered with @property, so it eases. The right one is a plain custom property with otherwise identical CSS, so it jumps partway through instead.
Each pair uses two different property names on purpose. @property registers a name for the whole page, not one element, so sharing a name would make both sides animate.
@property also takes inherits and initial-value, so a registered property behaves like a built-in one: a type, a default, and something the browser can animate. That’s where animated gradients, colors and counters come from, with no JavaScript anywhere.
turns, wins and reset, all CSS
trigonometry, in CSS
switch guests on