zudo-css

Type to search...

to open search from anywhere

@property

CreatedMar 13, 2026UpdatedMar 26, 2026Takeshi Takatsudo

The Problem

Standard CSS custom properties are untyped — the browser treats them as arbitrary strings. This means you cannot animate or transition custom properties (e.g., smoothly transitioning a gradient), the browser cannot validate their values, and inheritance behavior cannot be controlled. AI agents rarely use @property and instead resort to JavaScript animations or complex workarounds for effects that @property makes trivial.

The Solution

The @property at-rule lets you formally register a CSS custom property with a type (syntax), an initial value, and inheritance control. Once a property is typed, the browser can interpolate it — enabling smooth transitions and animations on values that were previously impossible to animate, like gradients, colors within gradients, and individual numeric values.

Code Examples

Basic @property Declaration

@property --primary-color {
  syntax: "<color>";
  inherits: true;
  initial-value: #2563eb;
}

@property --card-radius {
  syntax: "<length>";
  inherits: false;
  initial-value: 8px;
}

@property --opacity-level {
  syntax: "<number>";
  inherits: false;
  initial-value: 1;
}

Animating Gradients

Without @property, gradient transitions snap between states. With typed properties, smooth interpolation becomes possible.

@property --gradient-start {
  syntax: "<color>";
  inherits: false;
  initial-value: #3b82f6;
}

@property --gradient-end {
  syntax: "<color>";
  inherits: false;
  initial-value: #8b5cf6;
}

.hero-banner {
  background: linear-gradient(135deg, var(--gradient-start), var(--gradient-end));
  transition: --gradient-start 0.6s, --gradient-end 0.6s;
}

.hero-banner:hover {
  --gradient-start: #ec4899;
  --gradient-end: #f59e0b;
}

Animated Gradient Angle

@property --angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.rotating-gradient {
  background: linear-gradient(var(--angle), #3b82f6, #8b5cf6);
  animation: rotate-gradient 3s linear infinite;
}

@keyframes rotate-gradient {
  to {
    --angle: 360deg;
  }
}

Progress Indicator with Animated Percentage

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

.progress-ring {
  background: conic-gradient(
    #2563eb var(--progress),
    #e5e7eb var(--progress)
  );
  border-radius: 50%;
  transition: --progress 1s ease-out;
}

.progress-ring[data-value="75"] {
  --progress: 75%;
}

Type-Safe Design Tokens

@property --spacing-unit {
  syntax: "<length>";
  inherits: true;
  initial-value: 0.25rem;
}

@property --brand-hue {
  syntax: "<number>";
  inherits: true;
  initial-value: 220;
}

.design-system {
  --spacing-unit: 0.25rem;
  --brand-hue: 220;
}

.card {
  padding: calc(var(--spacing-unit) * 4);
  background: hsl(var(--brand-hue) 90% 95%);
  border: 1px solid hsl(var(--brand-hue) 60% 70%);
}

Controlling Inheritance

@property --section-bg {
  syntax: "<color>";
  inherits: false; /* Does NOT cascade to children */
  initial-value: transparent;
}

.section {
  --section-bg: #f0f9ff;
  background: var(--section-bg);
}

/* Nested sections get transparent (initial-value), not the parent's blue */
.section .section {
  /* --section-bg is transparent here because inherits: false */
  background: var(--section-bg);
}

Supported Syntax Types

/* All supported syntax descriptors */
@property --a { syntax: "<color>"; inherits: false; initial-value: black; }
@property --b { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --c { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
@property --d { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --e { syntax: "<integer>"; inherits: false; initial-value: 0; }
@property --f { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@property --g { syntax: "<time>"; inherits: false; initial-value: 0s; }
@property --h { syntax: "<resolution>"; inherits: false; initial-value: 1dppx; }
@property --i { syntax: "<length-percentage>"; inherits: false; initial-value: 0px; }
@property --j { syntax: "<image>"; inherits: false; initial-value: url(); }
@property --k { syntax: "<transform-function>"; inherits: false; initial-value: scale(1); }
@property --l { syntax: "<custom-ident>"; inherits: false; initial-value: none; }

/* Union types */
@property --m { syntax: "<color> | <length>"; inherits: false; initial-value: black; }

/* Universal (any value, like regular custom properties) */
@property --n { syntax: "*"; inherits: true; }

Browser Support

  • Chrome 85+
  • Edge 85+
  • Firefox 128+
  • Safari 15.4+

Global support exceeds 93%. Firefox added support in mid-2024, making @property available in all major browsers. The feature is Baseline Newly available as of July 2024.

Common AI Mistakes

  • Not using @property when trying to animate gradients or custom property values — resulting in abrupt snapping instead of smooth transitions
  • Using JavaScript-based animation (requestAnimationFrame) for effects that typed custom properties handle natively
  • Forgetting that all three descriptors (syntax, inherits, initial-value) are required (except initial-value when syntax is *)
  • Setting inherits: true when the property should be component-scoped, causing unintended cascade leakage
  • Not knowing that @property enables gradient animations — this is the most impactful and most overlooked use case
  • Confusing @property registration with the JavaScript CSS.registerProperty() API — the CSS at-rule is preferred for static definitions

When to Use

  • Smooth gradient transitions and animations (the primary killer use case)
  • Animated progress indicators, loading spinners, and visual effects using conic/radial gradients
  • Type-safe design tokens where the browser should validate property values
  • Controlling inheritance to prevent custom properties from cascading into nested components
  • Any animation that requires interpolating a custom property value

Live Previews

Animated Gradient with @property — Hover to see
Rotating Gradient Angle with @property

References

Revision History