files/en-us/web/css/reference/at-rules/@property/index.md
The @property CSS at-rule is used to explicitly define CSS custom properties, allowing for property type checking and constraining, setting default values, and defining whether a custom property can inherit values or not.
[!NOTE] The JavaScript {{domxref('CSS.registerProperty_static', 'registerProperty()')}} method is equivalent to the
@propertyat-rule.
@property --canBeAnything {
syntax: "*";
inherits: true;
}
@property --rotation {
syntax: "<angle>";
inherits: false;
initial-value: 45deg;
}
@property --defaultSize {
syntax: "<length> | <percentage>";
inherits: true;
initial-value: 200px;
}
The custom property name is a {{cssxref("dashed-ident")}} that starts with -- and is followed by a valid, user-defined identifier. It is case-sensitive.
@property inherits by default.The @property at-rule is part of the CSS Houdini set of APIs. It allows developers to explicitly define CSS custom properties, allowing for property type checking and constraining, setting default values, and defining whether a custom property can inherit values or not.
The @property rule enables custom property registration directly inside stylesheets without requiring any JavaScript. Valid @property rules produce registered custom properties, producing the same effect as calling {{domxref('CSS.registerProperty_static', 'registerProperty()')}} with equivalent parameters.
The following conditions must be met for the @property rule to be valid:
@property rule must include both the {{cssxref("@property/syntax","syntax")}} and {{cssxref("@property/inherits","inherits")}} descriptors.
If either is missing, the entire @property rule is invalid and ignored.syntax may be a data type name (such as <color>, <length>, or <number>, etc.), with multipliers (+, #) and combinators (|), a custom ident, or the universal syntax definition (*), meaning the syntax can be any valid token stream. The value is a {{cssxref("string")}}. As such, it must be in quotes.syntax descriptor is the universal syntax definition (syntax: "*").
If the initial-value descriptor is required but omitted, the entire @property rule is invalid and ignored.syntax descriptor is not the universal syntax definition, the {{cssxref("@property/initial-value","initial-value")}} descriptor has to be a computationally independent value.
This means the value can be converted into a computed value without depending on other values, except for "global" definitions independent of CSS.
For example, 10px is computationally independent—it doesn't change when converted to a computed value. 2in is also valid, because 1in is always equivalent to 96px. However, 3em is not valid, because the value of an em is dependent on the parent's {{cssxref("font-size")}}.@property rule.If multiple valid @property rules are defined using the same name, the last one in stylesheet order "wins". If custom properties are registered with the same name using @property in CSS and CSS.registerProperty() in JavaScript, the JavaScript registration wins.
{{csssyntax}}
In this example, we use the @property at-rule to declare two custom properties, and then use those properties in our style declarations.
<p>Hello world!</p>
@property --myColor {
syntax: "<color>";
inherits: true;
initial-value: rebeccapurple;
}
@property --myWidth {
syntax: "<length> | <percentage>";
inherits: true;
initial-value: 200px;
}
p {
background-color: var(--myColor);
width: var(--myWidth);
color: white;
}
{{ EmbedLiveSample('Basic example', '100%', '60px') }}
The paragraph should be 200px wide, with a purple background and white text.
In this example, we define a custom property called --progress using @property: this accepts {{cssxref("percentage")}} values and has an initial value of 25%. We use --progress to define the position value of the color stops in a {{cssxref("gradient/linear-gradient")}}, specifying where a green color stops, and black starts. We then animate the value of --progress to 100% over 2.5 seconds, giving the effect of animating a progress bar.
<div class="bar"></div>
@property --progress {
syntax: "<percentage>";
inherits: false;
initial-value: 25%;
}
.bar {
display: inline-block;
--progress: 25%;
width: 100%;
height: 5px;
background: linear-gradient(
to right,
#00d230 var(--progress),
black var(--progress)
);
animation: progressAnimation 2.5s ease infinite;
}
@keyframes progressAnimation {
to {
--progress: 100%;
}
}
{{ EmbedLiveSample('Animating a custom property value', '100%', '60px') }}
{{Specifications}}
{{Compat}}
--*)