Use @property while using CSS variables

Akash Shyam - Mar 9 '21 - - Dev Community

How many times has it happened with you when you specify a wrong thing into a CSS variable and spend hours debugging? Check out the new at-rule called @property.

What is @property?

The @property is part of CSS Houdini. It allows developers to define custom css properties. You might think, "Isn't that the point of CSS variables?". Well, when we use the var() function in css, it reads the variable as a string. When we use @property, it actually reads the data. It's basically css variables with superpowers.

Before @property came into the picture, we had to add javascript code to register a custom property.

CSS.registerProperty({
  name: '--color',
  syntax: '<color>',
  initialValue: 'yellow',
  inherits: false
});
Enter fullscreen mode Exit fullscreen mode

With the new @property, we can do something like this -

@property --color {
  syntax: "<color>";
  initial-value: magenta;
  inherits: false;
}
Enter fullscreen mode Exit fullscreen mode

Here we are defining a property called --color. We have specified a syntax field which says the type of value the variable should have. The some of the possible values of syntax are -

  • length
  • number
  • color
  • percentage
  • url
  • integer
  • angle
  • resolution

NOTE:- There may be more properties in the future, there is not a lot of documentation about this yet but I expect that this should improve.

Let's look at some code to understand this better.

@property --color {
  syntax: "<color>";
  initial-value: yellow;
  inherits: false;
}
Enter fullscreen mode Exit fullscreen mode

We have made a property called --color. We have specified that the syntax to check for is a color. This includes hex codes, rgb etc. We've set the initial-value to yellow. I'll explain what exactly initial-value does later. For now, let's add some code that uses this property.

.box {
  background: var(--color); /* yellow */
}
Enter fullscreen mode Exit fullscreen mode

The output is yellow. This is where the initial-value comes into play. Since we have not specified a --color variable inside .box, the color in the initial-value will be used.

Let's make a small change and define a variable of the same name as the property.

.box {
  --color: cyan;
  background: var(--color); /* cyan */
}
Enter fullscreen mode Exit fullscreen mode

Now, our output looks like this -

The color of the box is cyan as the --color variable overrides the intial-value of the --color property. You might say, "Akash, why can't I just use a CSS variable?". Remember the syntax property we specified? Let's understand what it means by making a tiny change in our code -

.box {
  --color: 234; /* Set the value to a number */
  background: var(--color); /* cyan */
}
Enter fullscreen mode Exit fullscreen mode

Look at the output:

As you can see, the color is yellow. This is because the value we set for the --color variable does not satisfy the <color> value we set for the syntax field. So, the property uses the initial-value i.e. yellow.

Check out the overall demo at this codepen:

Important Note on Browser Support

One thing you guys should keep in mind is that @propertyis experimental. It's available on Chrome, Opera and a few other browsers. I would not recommend using this in production level apps without fallbacks as of now.Check this link to know more

Why use @property?

  1. Fallbacks
    Let's imagine a developer forgot to define the property on the body and just used var(--whateverName). The value will fallback to the initial-value on the @property.

  2. Validation
    More often than not, the variable may have a different unit than the one required. For example, a developer may specify a number instead of a percentage. In these cases, the value specified may not be same as the value of the syntax property. The value will fall back to the initial-value and prevent bugs.

Thank you for reading until this point, that's all for now. Hope you guys liked this post and learned something new. If so, like the post and follow me. Have a good day, bye 👋

. . . . . . . . . . . . . . . . . . . . . . .