Using @property for CSS Custom Properties

Avatar of Chris Coyier
Chris Coyier on

Take your JavaScript to the next level at Frontend Masters.

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.