Using @property for CSS Custom Properties

Avatar of Chris Coyier
Chris Coyier on

DigitalOcean provides cloud products for every stage of your journey. Get started with $200 in free credit!

Una Kravetz digs into how Chrome now allows you to declare CSS custom properties directly from CSS with more information than just a string.

So rather than something like this:

html {
  --stop: 50%;
}

…can be declared with more details like this:

@property --stop {
  syntax: "<percentage>";
  initial-value: 50%;
  inherits: false;
}

The browser then knows this specific custom property is a percentage rather than a string. It can be other useful stuff like <integer> and <color>. Now that we have a way to communicate this sort of information to the browser, we get some new abilities, like being able to transition between two values.

While playing around, I noticed you have to very specifically call out the property to be transitioned (because a catch-all transition won’t do it). Try hovering on this demo, which is a re-creation of what Una did in the post:

Note that I’m animating the color stop’s position (which is a percentage), but I’m also trying to animate the color, which still does not work. I assumed it would with this new feature. I know people have been confused about the lack of being able to animate gradients for a long time. (See Ana Tudor’s article.)

You can always re-declare the properties somewhere at a high-level to “support” browsers that can’t read custom properties. Feels like a funny time to be talking about that. Safari seems to signal strong interest in this Houdini-based stuff, but hasn’t yet. Firefox? Eeesh, I dunno. Best we know is they labeled it as “Worth Prototyping” before all the layoffs.

This will also help with a the weird fallback issue with CSS custom properties that we mentioned in the newsletter:

As with any other custom property, you can get (using var) or set (write/rewrite) values, but with Houdini custom properties, if you set a falsey value when overriding it, the CSS rendering engine will send the initial value (its fallback value) instead of ignoring the line.