@property
@property CSS @ 规则是 CSS Houdini API 的一部分。它允许开发者显式地定义 CSS 自定义属性,从而可以进行属性类型检查、设置默认值,以及定义自定义属性是否可以继承值。
@property 规则表示直接在样式表中注册一个自定义属性,而无需运行任何 JavaScript。有效的 @property 规则会产生一个已注册的自定义属性,这类似于使用等效参数调用 registerProperty()。
语法
@property --rotation {
syntax: "<angle>";
inherits: false;
initial-value: 45deg;
}
自定义属性名是一个 <dashed-ident>,以 -- 开头,后跟一个有效的、用户定义的标识符。它区分大小写。
描述符
syntax-
一个描述已注册自定义属性允许的值类型的字符串。可以是一个数据类型名称(如
<color>、<length>或<number>等),可以带有乘数(+、#)和组合符(|),或者是一个自定义标识符。更多详情请参阅 syntax 描述符页面。 inherits-
一个布尔值,控制由
@property指定的自定义属性注册是否默认继承。 initial-value-
一个为属性设置初始值的值。
描述
@property 规则必须满足以下条件才有效
@property规则必须同时包含syntax和inherits描述符。如果缺少任何一个,整个@property规则都将无效并被忽略。- 如果
syntax描述符的值是通用语法定义(即syntax: "*"),则initial-value描述符是可选的。如果initial-value描述符是必需的但被省略了,则整个@property规则都将无效并被忽略。 - 如果
syntax描述符的值不是通用语法定义,那么initial-value描述符必须是一个计算无关的值。这意味着该值可以被转换为计算值而无需依赖其他值,除了那些独立于 CSS 的“全局”定义。例如,10px是计算无关的——它在转换为计算值时不会改变。2in也是有效的,因为1in总是等于96px。然而,3em是无效的,因为em的值依赖于父元素的font-size。 - 未知的描述符是无效的并且会被忽略,但不会使
@property规则失效。
正式语法
@property =
@property <custom-property-name> { <declaration-list> }
示例
使用 @property 注册和使用自定义属性
在这个例子中,我们定义了两个自定义属性,--item-size 和 --item-color,我们将用它们来定义下面三个项目的尺寸(宽度和高度)和背景颜色。
<div class="container">
<div class="item one">Item one</div>
<div class="item two">Item two</div>
<div class="item three">Item three</div>
</div>
以下代码使用 CSS @property @ 规则定义一个名为 --item-size 的自定义属性。该属性设置初始值为 40%,并将有效值限制为仅 <percentage> 类型的值。这意味着,当用作项目尺寸的值时,其尺寸将始终相对于其父元素的尺寸。该属性是可继承的。
@property --item-size {
syntax: "<percentage>";
inherits: true;
initial-value: 40%;
}
我们使用 JavaScript 而不是 CSS 来定义第二个自定义属性 --item-color。JavaScript 的 registerProperty() 方法等同于 @property @ 规则。该属性被定义为初始值为 aqua,只接受 <color> 类型的值,并且不可继承。
window.CSS.registerProperty({
name: "--item-color",
syntax: "<color>",
inherits: false,
initialValue: "aqua",
});
我们使用这两个自定义属性来设置项目的样式
.container {
display: flex;
height: 200px;
border: 1px dashed black;
/* set custom property values on parent */
--item-size: 20%;
--item-color: orange;
}
/* use custom properties to set item size and background color */
.item {
width: var(--item-size);
height: var(--item-size);
background-color: var(--item-color);
}
/* set custom property values on element itself */
.two {
--item-size: initial;
--item-color: inherit;
}
.three {
/* invalid values */
--item-size: 1000px;
--item-color: xyz;
}
两个自定义属性 --item-size: 20% 和 --item-color: orange; 设置在父元素 container 上,覆盖了这些自定义属性定义时设置的 40% 和 aqua 默认值。尺寸被设置为可继承;颜色则不是。
对于第一个项目,没有设置这些自定义属性。--item-size 是可继承的,所以使用了其父元素 container 上设置的 20% 值。另一方面,--item-color 属性是不可继承的,所以父元素上设置的 orange 值不会被考虑。而是使用了默认的初始值 aqua。
对于第二个项目,为两个自定义属性都设置了 CSS 全局关键字,这些关键字对所有值类型都有效,因此无论 syntax 描述符的值是什么都是有效的。--item-size 被设置为 initial,并使用在 @property 声明中设置的 initial-value: 40%;。initial 值意味着使用该属性的 initialValue 值。--item-color 被设置为 inherit,明确地从其父元素继承了 orange 值,尽管该自定义属性被设置为不可继承。这就是为什么第二个项目是橙色的。
对于第三个项目,--item-size 的值被设置为 1000px。虽然 1000px 是一个 <length> 值,但 @property 声明要求该值是 <percentage>,因此该声明无效并被忽略,这意味着使用了父元素上设置的可继承的 20% 值。xyz 值也是无效的。由于 registerProperty() 将 --item-color 设置为不可继承,因此使用的是默认的初始值 aqua,而不是父元素的 orange 值。
为自定义属性值添加动画
在这个例子中,我们使用 @property 定义了一个名为 --progress 的自定义属性:它接受 <percentage> 值,并且初始值为 25%。我们使用 --progress 来定义 linear-gradient() 中颜色断点的位置值,指定绿色停止和黑色开始的位置。然后,我们在 2.5 秒内将 --progress 的值动画化到 100%,从而产生进度条动画的效果。
<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%;
}
}
规范
| 规范 |
|---|
| CSS 属性和值 API Level 1 # at-property-rule |
浏览器兼容性
加载中…