MyInternships.in

CSS Advanced

CSS @property

Plain CSS variables are untyped text, so the browser cannot animate them. The @property at-rule registers a custom property with a type, an inheritance flag and an initial value, which unlocks animation, better validation and gradient interpolation. This guide explains it with live examples.


Why @property Exists

A normal custom property is just a string. Because the browser does not know whether --angle holds a number, a colour or a length, it cannot smoothly interpolate it during a transition or animation. @property tells the browser the property's type, so it can animate the value and reject invalid input.

Syntax

@property takes a property name and three descriptors: syntax (the type), inherits (whether it cascades to children), and initial-value (a required default).

@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
DescriptorMeaningExample
syntaxThe allowed value type"<color>", "<length>", "<number>"
inheritsWhether it inherits to descendantstrue / false
initial-valueRequired default value0deg, #000, 0px
syntax valueAccepts
"<length>"Lengths like 10px, 2rem
"<color>"Colours like #f00, red
"<number>"Plain numbers
"<percentage>"Percentages
"<angle>"Angles like 45deg, 0.5turn
"*"Any value (untyped, not animatable)

Animating a Registered Angle

Registering --angle as an <angle> lets a conic gradient spin. Without @property the same keyframes would jump instead of rotating smoothly, because the variable would be treated as text.

Run this — a smoothly rotating gradient border
Example
<!DOCTYPE html>
<html>
<head>
<style>
  @property --angle {
    syntax: "<angle>";
    inherits: false;
    initial-value: 0deg;
  }
  .spinner {
    width: 140px; height: 140px; border-radius: 50%;
    background: conic-gradient(from var(--angle), #6366f1, #ec4899, #6366f1);
    animation: spin 3s linear infinite;
  }
  @keyframes spin {
    to { --angle: 360deg; }
  }
</style>
</head>
<body>
  <div class="spinner"></div>
</body>
</html>

Animating a Typed Number

Run this — a counting-style progress fill
Example
<!DOCTYPE html>
<html>
<head>
<style>
  @property --p {
    syntax: "<percentage>";
    inherits: false;
    initial-value: 0%;
  }
  .bar {
    height: 22px; border-radius: 999px;
    background: linear-gradient(#22c55e, #22c55e) left / var(--p) 100% no-repeat, #e5e7eb;
    transition: --p 1.2s ease;
  }
  .bar:hover { --p: 100%; }
</style>
</head>
<body>
  <div class="bar"></div>
  <p style="font:13px sans-serif">Hover the bar to fill it.</p>
</body>
</html>
💡

@property can also be registered from JavaScript with CSS.registerProperty({ name, syntax, inherits, initialValue }), which is handy when tokens are generated dynamically.

⚠️

initial-value is mandatory for any syntax except "*". Omitting it makes the whole @property rule invalid and it is ignored.

Key points

  • @property registers a custom property with a type so the browser can animate it.
  • It needs three descriptors: syntax, inherits and initial-value.
  • Typed properties interpolate smoothly in transitions and keyframes.
  • syntax: "*" is untyped and, like plain variables, cannot be animated.
  • initial-value is required unless syntax is "*".

Related CSS Topics

Keep learning with these closely related tutorials.

Ready to use your CSS skills?

Find web development internships and fresher jobs across India.

Browse Web Dev Internships