Using @property for Custom CSS Properties

This is a "Today I Learned" post - a quick note about something I discovered.
Topic: css

Today I learned about the CSS @property rule, which allows us to define and type-check our CSS custom properties (variables)!

The problem it solves

Regular CSS custom properties (using --varname) don’t have types or inheritance controls. The browser treats them all as strings and doesn’t validate their values. With @property, we can specify types, default values, and inheritance behavior.

Basic usage

@property --my-color {
  syntax: '<color>';
  initial-value: red;
  inherits: true;
}

.element {
  background-color: var(--my-color);
}

The syntax field specifies the allowed type, initial-value defines the default, and inherits controls whether the property inherits to child elements.

Practical example: Smooth transitions

One of the coolest things about @property is that it enables animations and transitions on properties that wouldn’t normally interpolate:

🦊
@property --fox-rotate {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

.fox {
  transition: --fox-rotate 0.5s ease;
  transform: rotate(var(--fox-rotate));
}

.fox-container:hover .fox {
  --fox-rotate: 360deg;
}

Hover over the fox to see it spin! Without @property, you couldn’t transition between angle values like this because the browser wouldn’t know how to interpolate between them.

Other types you can define

The @property rule supports many value types:

  • <color> - Any valid CSS color
  • <length> - Values like 10px, 2em
  • <percentage> - Values like 50%
  • <angle> - Values like 45deg, 1turn
  • <time> - Values like 300ms, 2s
  • <integer> - Whole numbers
  • <number> - Any number, including decimals