The Times You Need A Custom @property Instead Of A CSS Variable<\/h1>\nPreethi Sam<\/address>\n 2024-05-13T08:00:00+00:00
\n 2025-03-19T12:04:52+00:00
\n <\/header>\n
We generally use a CSS variable as a placeholder for some value we plan to reuse \u2014 to avoid repeating the same value and to easily update that value across the board if it needs to be updated.<\/p>\n
:root { \n --mix: color-mix(in srgb, #8A9B0F, #fff 25%);\n}\n\ndiv {\n box-shadow: 0 0 15px 25px var(--mix);\n}\n<\/code><\/pre>\nWe can register custom<\/em> properties in CSS using @property<\/code>. The most common example you\u2019ll likely find demonstrates how @property<\/code> can animate the colors of a gradient<\/a>, something we\u2019re unable to do otherwise since a CSS variable is recognized as a string and what we need is a number format that can interpolate between two numeric values. That\u2019s where @property<\/code> allows us to define not only the variable\u2019s value<\/em> but its syntax,<\/em> initial value<\/em>, and inheritance<\/em>, just like you\u2019ll find documented in CSS specifications.<\/p>\nFor example, here\u2019s how we register a custom property called --circleSize<\/code>, which is formatted as a percentage value that is set to 10%<\/code> by default and is not inherited by child elements.<\/p>\n@property --circleSize {\n syntax: \"\";\n inherits: false;\n initial-value: 10%;\n}\n\ndiv { \/* red div *\/\n clip-path: circle(var(--circleSize) at center bottom);\n transition: --circleSize 300ms linear;\n}\n\nsection:hover div { \n --circleSize: 125%; \n}\n<\/code><\/pre>\nIn this example, a circle()<\/code><\/a> function is used to clip the <\/p>\n<\/div>\n<\/code> element into \u2014 you guessed it \u2014 a circle. The size value of the circle()<\/code>\u2019s radius is set to the registered custom property, --circleSize<\/code>, which is then independently changed on hover using a transition<\/code>. The result is something close to Material Design\u2019s ripple effect<\/a>, and we can do it because we\u2019ve told CSS to treat the custom property as a percentage value rather than a string:<\/p>\n\nSee the Pen [CSS @property [forked]](https:\/\/codepen.io\/smashingmag\/pen\/PovwepK) by Preethi Sam<\/a>.<\/p>See the Pen CSS @property [forked]<\/a> by Preethi Sam<\/a>.<\/figcaption><\/figure>\n\n\n <\/p>\nThe freedom to define and spec our own CSS properties gives us new animating superpowers that were once only possible with JavaScript, like transitioning the colors of a gradient.<\/p>\n
<\/a>\n <\/p>\n
\n\n \u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\nHere\u2019s an idea I have that uses the same basic idea as the ripple, only it chains multiple custom properties together that are formatted as colors, lengths, and angle degrees for a more complex animation where text slides up the container as the text changes colors.<\/p>\n\nSee the Pen [Text animation with @property [forked]](https:\/\/codepen.io\/smashingmag\/pen\/rNgavyb) by Preethi Sam<\/a>.<\/p>See the Pen Text animation with @property [forked]<\/a> by Preethi Sam<\/a>.<\/figcaption><\/figure>\nLet\u2019s use this demo as an exercise to learn more about defining custom properties with the @property<\/code> at-rule, combining what we just saw in the ripple with the concept of interpolating gradient values.<\/p>\n\n
\n 2025-03-19T12:04:52+00:00
\n <\/header>\n
:root { \n --mix: color-mix(in srgb, #8A9B0F, #fff 25%);\n}\n\ndiv {\n box-shadow: 0 0 15px 25px var(--mix);\n}\n<\/code><\/pre>\nWe can register custom<\/em> properties in CSS using @property<\/code>. The most common example you\u2019ll likely find demonstrates how @property<\/code> can animate the colors of a gradient<\/a>, something we\u2019re unable to do otherwise since a CSS variable is recognized as a string and what we need is a number format that can interpolate between two numeric values. That\u2019s where @property<\/code> allows us to define not only the variable\u2019s value<\/em> but its syntax,<\/em> initial value<\/em>, and inheritance<\/em>, just like you\u2019ll find documented in CSS specifications.<\/p>\nFor example, here\u2019s how we register a custom property called --circleSize<\/code>, which is formatted as a percentage value that is set to 10%<\/code> by default and is not inherited by child elements.<\/p>\n@property --circleSize {\n syntax: \"\";\n inherits: false;\n initial-value: 10%;\n}\n\ndiv { \/* red div *\/\n clip-path: circle(var(--circleSize) at center bottom);\n transition: --circleSize 300ms linear;\n}\n\nsection:hover div { \n --circleSize: 125%; \n}\n<\/code><\/pre>\nIn this example, a circle()<\/code><\/a> function is used to clip the <\/p>\n<\/div>\n<\/code> element into \u2014 you guessed it \u2014 a circle. The size value of the circle()<\/code>\u2019s radius is set to the registered custom property, --circleSize<\/code>, which is then independently changed on hover using a transition<\/code>. The result is something close to Material Design\u2019s ripple effect<\/a>, and we can do it because we\u2019ve told CSS to treat the custom property as a percentage value rather than a string:<\/p>\n\nSee the Pen [CSS @property [forked]](https:\/\/codepen.io\/smashingmag\/pen\/PovwepK) by Preethi Sam<\/a>.<\/p>See the Pen CSS @property [forked]<\/a> by Preethi Sam<\/a>.<\/figcaption><\/figure>\n\n\n <\/p>\nThe freedom to define and spec our own CSS properties gives us new animating superpowers that were once only possible with JavaScript, like transitioning the colors of a gradient.<\/p>\n
<\/a>\n <\/p>\n
\n\n \u201c<\/span><\/div>\n<\/p><\/div>\n<\/blockquote>\nHere\u2019s an idea I have that uses the same basic idea as the ripple, only it chains multiple custom properties together that are formatted as colors, lengths, and angle degrees for a more complex animation where text slides up the container as the text changes colors.<\/p>\n\nSee the Pen [Text animation with @property [forked]](https:\/\/codepen.io\/smashingmag\/pen\/rNgavyb) by Preethi Sam<\/a>.<\/p>See the Pen Text animation with @property [forked]<\/a> by Preethi Sam<\/a>.<\/figcaption><\/figure>\nLet\u2019s use this demo as an exercise to learn more about defining custom properties with the @property<\/code> at-rule, combining what we just saw in the ripple with the concept of interpolating gradient values.<\/p>\n\n