1. 介绍
CSS 定义了一套全面的属性,可以通过操作这些属性来修改网页文档的布局、绘制或行为。然而,网页作者常常希望通过额外的属性来扩展这套属性。
[css-variables] 提供了定义用户控制属性的基本方法, 但这些属性总是以令牌列表作为值,必须始终继承,并且只能通过 var() 引用重新并入其他属性的值中,来影响文档的布局或绘制。
本规范扩展了[css-variables],允许注册具有值类型、初始值和定义的继承行为的属性, 通过两种方法:
-
JS API,
registerProperty()方法 -
CSS at-rule,@property 规则
本规范是[css-paint-api-1]和[css-layout-api-1]的补充, 允许自定义属性直接影响绘制和布局行为。
2. 注册的自定义属性
自定义属性可以成为一个注册的自定义属性,
使其更像用户代理定义的属性:
赋予它一个由用户代理检查的语法,
一个初始值,
和特定的继承行为。
这可以通过@property 规则,
或registerProperty()
JS 函数来实现。
自定义属性在文档中被视为注册,
如果其名称在文档的样式表中有一个有效的@property 规则定义,
或其名称在文档的[[registeredPropertySet]]
槽中包含
(即,registerProperty()
被调用来注册它)。
注册的自定义属性 的行为类似于未注册的 自定义属性, 只是如下面定义的那样。
2.1. 确定注册
一个注册的自定义属性具有一个自定义属性注册, 包含处理它如真实属性所需的所有数据。 它是一个结构 ,由以下内容组成:
-
一个属性名称(一个自定义属性名称字符串)
-
一个语法(一个语法字符串)
-
一个继承标志(一个布尔值)
如果文档的
[[registeredPropertySet]]
槽包含一个记录,其自定义属性的名称,
注册即该记录。
否则,
如果文档的
活动样式表包含至少一个有效的@property 规则
表示与自定义属性的名称的注册,
文档顺序中的最后一个注册即为该注册。
2.2. 解析时行为
注册的自定义属性的解析方式与未注册的自定义属性完全相同; 几乎允许任何内容。 属性的注册语法在解析时不被检查。
注意:然而, 语法在计算值时被检查, 在通过var()进行替换之前。 参见§ 2.4 计算值时的行为。
为什么不对自定义属性进行语法检查?
在解析页面的 CSS 时, 用户代理通常会进行多项优化 以帮助提高速度和内存使用。
其中一个优化 是仅存储实际会产生影响的属性; 它们会丢弃无效的属性, 如果在单个声明块中多次写入同一属性, 除最后一个有效的属性外,所有其他属性都会被丢弃。 (这是 CSS 的错误恢复 和向前兼容行为的重要部分。)
如果属性的语法在页面的生命周期内从未变化,这种方法是有效的。 但是,如果自定义属性已注册, 它可以更改其语法, 以便之前无效的属性 突然变为有效。
处理这一点的唯一方法是要么存储每个声明, 即使那些最初无效的声明 (增加页面的内存成本), 要么使用新的语法规则重新解析整个页面的 CSS (增加注册自定义属性的处理成本)。 这两者都不是非常理想的选择。
此外, 用户代理定义的属性的语法由用户查看页面时的用户代理版本决定; 这超出了页面作者的控制范围, 这就是 CSS 的错误恢复行为的整个原因 和针对不同支持级别编写多个声明的实践。 而自定义属性的语法由页面作者控制, 根据他们在页面中包含的样式表或脚本; 没有不可预测性需要管理。 丢弃违反语法的自定义属性 因此只会对页面作者来说是一种便利, 而不是像用户代理定义的属性那样的必要性。
2.3. 指定值-时间行为
就像未注册的自定义属性一样, 所有注册自定义属性,无论注册语法如何, 都接受CSS宽关键字, 例如继承或还原。 其行为在CSS 级联 4 § 7.3 明确默认值中定义。
2.4. 计算值-时间行为
如果注册的语法是通用语法定义, 则计算值与未注册的自定义属性相同 (要么是替换变量后的指定值,要么是保证无效值)。
否则,尝试解析该属性的值 根据其注册语法。 如果失败, 声明在计算值时间无效,而计算值将相应确定。 如果成功, 计算值依赖于语法的具体情况:
对于"<length>"、"<length-percentage>"、"<angle>"、
"<time>"、"<resolution>"、"<integer>"、
"<number>"、
和"<percentage>"值:
-
如果指定值是任何其他数字字面量 (例如5或20%), 则计算值如指定。 (特别是,百分比永远不会与任何内容解析。)
-
如果指定值是一个计算为这些类型的函数 (例如数学函数), 则计算值由该函数定义。
对于"<color>"值,
通过解析颜色值来计算值,
根据CSS 颜色 4 § 14.
解析<color>值。
对于"<custom-ident>"、标识符或"*"值,
计算值如指定。
对于"<url>"值,
计算值为以下之一:
-
如果 URL 是相对 URL, 则计算值为解析后的绝对 URL,如[css3-values]中所述。
-
否则,计算值如指定。
URL 行为示例
例如,假设--url-foo和--url-bar是具有<url>语法的注册
自定义属性,并且我们有一个样式表在/style/foo/foo.css:
div{ --url-foo : url ( "foo.png" ); }
还有另一个样式表在/style/bar/bar.css
div{ --url-bar : url ( "bar.png" ); }
最后,一个文档在/index.html:
< link href = "/style/foo/foo.css" rel = "stylesheet" type = "text/css" > < link href = "/style/bar/bar.css" rel = "stylesheet" type = "text/css" > < div style = "background-image: var(--url-foo), var(---url-bar);" > </ div >
在这里,var(--url-foo) 引用会生成一个解析为/style/foo的URL,而var(--url-bar) 引用会生成一个解析为/style/bar的URL。
另一方面,如果--url-foo和--url-bar都是未注册的,它们将把它们的字面值(相对URL)替换到/index.html样式表中,然后将这些URL解析为/index.html。
对于"<image>"值,计算值是计算的<image>。
对于"<transform-function>"和"<transform-list>"值,计算值按规定生成,但所有长度会解析为其计算值。
对于带有乘数的值,计算值是基本类型的计算值列表。
对于用| 组合符指定的语法,计算值由匹配该值的第一条子句的计算值规则应用给出。
2.5. 动画行为
注意: 根据[css3-animations]和[css3-transitions]的定义,可以指定引用自定义属性的动画和过渡。
当通过动画和过渡引用时,自定义属性值会插值 按计算值,根据解析的类型。
注意:
这意味着值的列表,如<color>+或<color>#,会插值为简单列表,逐个匹配每个组件索引,如果组件数量不匹配则会失败。
作为上述规则的例外,解析为<transform-list>、<transform-function>或<transform-function>+的值则按transform属性插值。
注意:
如果出于某种原因,自定义属性定义为<transform-function>#,则首先会插值为简单列表,然后每个列表项将插值为transform值。
注意: 注册(或更改注册)自定义属性可以改变其计算值,这可以开始或中断CSS过渡。
2.6. 条件规则
如§ 2.2 解析时行为中所述,无论是未注册的还是注册的 自定义属性在解析时都接受(几乎)所有可能的值。注册的 自定义属性仅在计算值时应用其语法。
因此,所有自定义属性,无论是注册还是未注册,都将在@supports规则中测试为“true”,只要不违反自定义属性的(非常宽松的)通用语法。
syntax : "<color>" ; 注册,像@supports (--foo: 1em) {...}这样的规则仍会评估为true并应用这些样式,因为该声明确实成功解析为有效的属性。
2.7. 通过 var() 的替换
与未注册的自定义属性一样, 注册的自定义属性的值可以使用 var() 函数替换为另一个值。 然而,注册的自定义属性作为其 计算值 进行替换,而不是用于生成该值的原始标记序列。
任何引用注册自定义属性的 var() 函数 必须被替换为 等效标记序列, 它等于通过 序列化 计算值生成的标记序列, 并 标记化 结果字符串。
div{ font-size : 10 px ; --x : 8 em ; --y : var ( --x); }
因为 --x 的计算值(序列化时) 是 "80px",所以 --y 的计算值是 一个 <dimension-token>,其值为 "80" 和单位 "px"。
2.7.1. 在 var() 引用中的后备值
使用 var() 函数引用注册自定义属性 时 可以提供后备值。然而,后备值必须与被引用的自定义属性的 语法定义 匹配,否则声明在 计算值时间无效。
注意: 无论后备值是否被使用,这都适用。
2.7.2. 通过相对单位的依赖循环
注册自定义属性 遵循与未注册的 自定义属性 相同的依赖循环解析规则, 并附加以下约束:
对于任何具有 <length> 或 <length-percentage> 语法组件的注册自定义属性:
-
如果该属性包含以下任何单位: em, ex, cap, ch, ic, lh; 那么在该属性与当前元素的 font-size 之间添加一条边。
-
如果该属性包含 lh 单位, 在该属性与当前元素的 line-height 之间添加一条边。
-
如果该属性包含 rlh 单位, 在该属性与根元素的 line-height 之间添加一条边。
CSS. registerProperty({ name: "--my-font-size" , syntax: "<length>" , initialValue: "0px" , inherits: false });
以下代码将产生一个依赖循环:
div{ --my-font-size : 10 em ; font-size : var ( --my-font-size); }
而 font-size 的行为将表现得好像指定了 unset 值。
2.8. 影子 DOM
与 CSS 中的许多概念不同
(参见 CSS Scoping 1 § 3.5
名称定义构造和继承),
属性注册 不是 作用于树范围。
所有注册,
无论它们出现在最外层文档中
还是在影子树中,
都在一个全球注册图中交互,
适用于 文档。
为什么注册不能作用于范围?
对于属性注册作用于范围的情况是明确的—使用影子 DOM 的组件 并注册一些自定义属性 可能并不打算让外部页面 查看该注册, 因为外部页面甚至不知道该组件正在使用该属性。
然而,也有不作用于注册范围的理由—自定义属性用于将数据 导入 组件, 外部页面能够设置这些自定义属性 并让注册进行语法检查是很有用的; 同样,属性的初始值等概念 只有在属性注册全局存在时才有意义, 因此它适用于文档根部的属性。
但以上只是意味着注册范围 可能是应当可控的东西, 而不是强制全局。
注册必须是全局的原因 是因为元素可以同时存在于多个树范围中, 各个树范围的样式 会交错并共同级联。 这适用于 宿主元素, 它生活在外部树中 但可以通过 :host 选择器从影子树中进行样式化, 同样,影子 DOM 内的元素 也可以通过外部树中的 ::part() 伪元素进行目标选择。
如果注册可以作用于树范围, 而一个单一属性在内外两处注册, 那么不清楚应该应用哪个注册 来解析值。 即使我们追踪值来自哪个树 (这是我们对其他树作用值所做的) 并应用相应的注册, 也不清楚这是否会产生合理的结果—影子 DOM 可能期望某个属性有 特定的值空间, 并且在接收到完全不同的值时会感到惊讶, 因为外部树赢得了级联 并应用了它自己的注册。
当自定义属性作为使用影子 DOM 的组件的公共 API 的一部分暴露时, 这种全局注册行为会按预期工作。 如果外部页面使用同名的自定义属性 进行不同目的, 那已经是需要解决的冲突, 而注册行为并没有使情况变得更糟。
然而,如果自定义属性旨在用于组件的私有内部使用, 建议给该属性 取一个可能唯一的名称, 以最小化与其他上下文发生冲突的可能性。 这可以通过包含项目名称 或一些简短的随机字符串 来实现。
3. @property 规则
@property 规则在样式表中直接表示 自定义属性注册
而无需运行任何 JS。
有效的 @property 规则会导致一个 注册的自定义属性,
就好像 registerProperty()
被调用并使用了等效的参数。
@property 的语法是:
@property <custom-property-name> {
<declaration-list>
}
有效的 @property 规则表示一个 自定义属性注册, 其属性名称为规则前导中的 <custom-property-name> 的序列化。
@property 规则需要 语法 和 继承 描述符; 如果缺少任一项, 整个规则都是无效的,必须被忽略。 初始值 描述符只有在语法为 通用语法定义 时是可选的, 否则该描述符是必需的; 如果缺失,整个规则无效,必须被忽略。
未知的描述符是无效的并被忽略, 但不会使 @property 规则无效。
注意: 如 § 2.1 确定注册
中规定,
如果为同一个 <custom-property-name> 定义多个有效的 @property 规则,
则样式表中最后一个的“胜出”。
来自 CSS.registerProperty()
的自定义属性注册优先于同一个 <custom-property-name> 的任何 @property 规则。
3.1. 语法描述符
| 名称: | 语法 |
|---|---|
| 适用于: | @property |
| 值: | <string> |
| 初始: | 不适用 (见正文) |
指定由 自定义属性注册 表示的 @property 规则的语法, 控制属性值在 计算值 时的解析。
语法 描述符是 @property 规则有效的必需项; 如果缺失,@property 规则无效。
如果提供的字符串不是有效的 语法字符串 (如果在调用 消费语法定义 时返回失败), 则该描述符无效,必须被忽略。
3.2. inherits 描述符
| 名称: | inherits |
|---|---|
| 适用于: | @property |
| 值: | true | false |
| 初始: | n/a(见正文) |
指定由 自定义属性注册 代表的 @property 规则的继承标志,控制属性是否默认继承。
inherits 描述符对于 @property 规则是必需的; 如果缺失,则 @property 规则无效。
3.3. initial-value 描述符
| 名称: | initial-value |
|---|---|
| 适用于: | @property |
| 值: | <declaration-value>? |
| 初始: | 保证无效值(但见正文) |
指定由 自定义属性注册 代表的 @property 规则的初始值,控制属性的 初始值。
如果 syntax 描述符的值为 通用语法定义, 则 initial-value 描述符是可选的。 如果省略,属性的 初始值 是 保证无效值。
否则, 如果 syntax 描述符的值不是 通用语法定义, 则必须满足以下条件,以使 @property 规则有效:
-
必须存在 initial-value 描述符。
-
initial-value 描述符的值必须 根据语法成功解析。
-
initial-value 必须是 计算独立。
如果不满足上述条件,则 @property 规则无效。
4. 在 JS 中注册自定义属性
要通过 JS 注册自定义属性,
CSS 对象扩展了一个 registerProperty()
方法:
dictionary PropertyDefinition {required DOMString name ;DOMString syntax = "*";required boolean inherits ;DOMString initialValue ; };partial namespace CSS {undefined registerProperty (PropertyDefinition ); };definition
Additional, the Document
object gains a new [[registeredPropertySet]]
private slot,
which is a set of records that describe registered custom properties.
4.1.
registerProperty()
函数
该 registerProperty(PropertyDefinition definition) 方法
根据 definition 中提供的配置选项注册自定义属性。
当调用时,
它执行 注册自定义属性 算法,
将 definition 参数中的选项作为相同名称的参数传递。
-
让 property set 为 当前全局对象的 关联的
Document的[[registeredPropertySet]]槽的值。 -
如果 name 不是 自定义属性名称字符串, 抛出
SyntaxError并退出此算法。如果 property set 已包含 name 作为其属性名称的条目 (按代码点比较), 抛出
InvalidModificationError并退出此算法。 -
尝试从 syntax 中 消费一个语法定义。 如果返回失败, 抛出
SyntaxError。 否则,让 syntax definition 为返回的 语法定义。 -
如果 syntax definition 是 通用 语法定义, 且 initialValue 不存在, 让 parsed initial value 为空。 这必须与自定义属性的“默认”初始值相同, 如 [css-variables] 中定义。 跳到算法的下一步。
否则, 如果 syntax definition 是 通用 语法定义, 解析 initialValue 为 <declaration-value>。 如果失败, 抛出
SyntaxError并退出此算法。 否则, 让 parsed initial value 为解析结果。 跳到算法的下一步。否则,如果 initialValue 不存在, 抛出
SyntaxError并退出此算法。否则, 解析
initialValue根据 syntax definition。 如果失败, 抛出SyntaxError并退出此算法。否则,让 parsed initial value 为解析结果。 如果 parsed initial value 不是 计算独立的, 抛出
SyntaxError并退出此算法。 -
将 inherit flag 设置为 inherits 的值。
-
让 registered property 为一个 结构体,其属性 名称为 name, 语法为 syntax definition, 初始值为 parsed initial value, 以及继承标志为 inherit flag。 附加 registered property 到 property set。
属性值是 计算独立的,如果它可以仅使用元素上属性的值和不能被 CSS 改变的“全局”信息转换为计算值。
另一方面, 3em 不是 计算独立的, 因为它依赖于元素(或元素父级)的 font-size 的值。 值也不是 var() 函数,因为它依赖于 自定义属性 的值。
当自定义属性使用特定类型注册时, 该属性的指定值如何转换为计算值的过程由所选类型完全定义, 如 § 2.4 计算值时行为 中所述。
注意: 未来可能会添加注销属性的方法。
注册自定义属性不得以任何方式影响 级联。 不管注册属性指定什么语法, 在解析时它仍然被视为普通的 自定义属性, 准许几乎任何内容。 如果 指定值 对于 注册自定义属性 违反注册语法, 则该属性在计算值时变为无效(因此重置为注册的初始值)。
.thing{ --my-color : green; --my-color : url ( "not-a-color" ); color : var ( --my-color); }
是将类为 "thing" 的元素的 color 属性设置为 inherit。 第二个 --my-color 声明在解析时覆盖第一个(两者都是有效的), 而在 color 属性中的 var() 引用被发现为 在计算值时无效(因为 url("not-a-color") 不是颜色)。 在 CSS 管道的这个阶段(计算时间), 唯一可用的后备是属性的初始值, 对于颜色而言是 inherit。 尽管有一个有效可用值(green), 但在解析期间由于被 URL 取代而被移除。
如果我们调用:
CSS. registerProperty({ name: "--my-color" , syntax: "<color>" , initialValue: "black" , inherits: false });
解析并不会显著改变, 无论注册发生在上面的样式表之前还是之后。 唯一的区别是 --my-color 属性变为 在计算值时无效, 并设置为其初始值 black; 然后 color 被 有效地设置为 black, 而不是在计算值时无效并变为 inherit。
4.2.
属性定义 PropertyDefinition
字典
PropertyDefinition 字典表示
作者指定的自定义属性配置选项。 PropertyDefinition
字典包含以下成员:
name, 类型为 DOMString-
定义的自定义属性的名称。
syntax, 类型为 DOMString,默认为"*"-
表示此自定义属性如何解析的字符串。
inherits, 类型为 boolean-
如果该自定义属性应该沿着 DOM 树继承,则为真;否则为假。
initialValue, 类型为 DOMString-
此自定义属性的初始值。
5. 语法字符串
语法字符串 描述 注册的自定义属性接受的值类型。语法字符串由 语法组件名称 组成, 可选地 乘以 和 组合。
语法字符串可以解析为 语法定义,其形式为:
-
一组 语法组件,每个组件接受在 § 5.1 支持的名称 中指定的值类型,或
-
通用语法定义 universal syntax definition (*),接受任何有效的标记流。
注意: 无论指定什么语法,所有自定义属性都接受 CSS-wide 关键字,并适当地处理这些值。
"<length>"-
接受长度值
"<length> | <percentage>"-
接受长度、百分比、百分比计算表达式和长度计算表达式,但不接受包含长度和百分比值组合的计算表达式。
"<length-percentage>"-
接受所有
"<length> | <percentage>"接受的值,以及包含长度和百分比值组合的计算表达式。 "big | bigger | BIGGER"-
接受标识符
big、bigger或BIGGER。 "<length>+"-
接受空格分隔的长度值列表。
- "*"
-
接受任何有效的标记流
注意: 语法字符串的内部语法是 CSS 值定义语法 的子集。预计本规范的未来版本将扩展允许的语法的复杂性,使自定义属性更接近 CSS 属性允许的全部内容。
本章的其余部分描述语法字符串的内部语法。
5.1. 支持的名称
本节定义了 支持的语法组件名称,以及生成的 语法组件 所接受的相应类型。
- "<length>"
-
任何有效的 <length> 值
- "<number>"
-
<number> 值
- "<percentage>"
-
任何有效的 <percentage> 值
- "<length-percentage>"
-
任何有效的 <length> 或 <percentage> 值,任何有效的 <calc()> 表达式组合 <length> 和 <percentage> 组件。
- "<color>"
-
任何有效的 <color> 值
- "<image>"
-
任何有效的 <image> 值
- "<url>"
-
任何有效的 <url> 值
- "<integer>"
-
任何有效的 <integer> 值
- "<angle>"
-
任何有效的 <angle> 值
- "<time>"
-
任何有效的 <time> 值
- "<resolution>"
-
任何有效的 <resolution> 值
- "<transform-function>"
-
任何有效的 <transform-function> 值
- "<custom-ident>"
-
任何有效的 <custom-ident> 值
- 任何序列 以标识符开头、可以被视为名称,并与 <custom-ident> 生成匹配
-
该标识符
注意: <custom-ident> 是逐码点比较的; 这与 UA 定义的 CSS 的正常行为不同,后者仅限于 ASCII 并且是 ASCII 不区分大小写。 因此,指定 ident 如
Red意味着接受精确值 Red; red、RED 及任何其他大小写变体均不匹配。 建议将 idents 限制为 ASCII,并以小写字母书写, 以符合 CSS 约定。 - "<transform-list>"
-
有效的 <transform-function> 值的列表。注意
"<transform-list>"是等同于"<transform-function>+"的 预乘数据类型名称
注意: 语法字符串 "*" 将产生
通用语法定义,这不是 语法组件。
因此,"*" 可能不能被 乘以 或 与其他东西结合。
5.2. “+” 和 “#” 乘数
除了 预乘数据类型名称 之外,任何 语法组件名称 后面可以紧跟一个乘数:
- U+002B 加号 (+)
-
表示一个空格分隔的列表。
- U+0023 井号 (#)
-
表示一个逗号分隔的列表。
注意: 乘数必须紧跟在被乘的 语法组件名称 之后出现。
5.3. “|” 组合符
语法字符串 可以使用 U+007C 竖线 (|) 提供多个 语法组件名称。这样的语法字符串将导致生成一个 语法定义 ,其中包含多个 语法 组件。
当一个 语法 定义 具有多个 语法组件 时, 用于解析 CSS 值时,语法组件将按指定顺序匹配。
注意: 即,给定语法字符串
"red | <color>",
将匹配值 red
解析为标识符,
而匹配值 blue 将
解析为 <color>。
5.4. 解析语法字符串
5.4.1. 定义
- 数据类型 名称
-
一系列 代码点,由一个 U+003C 小于号 (<) 开头, 后接零个或多个 标识符代码点,并以 U+003E 大于号 (>) 结束。
- 预乘数据类型名称
- 语法 组件
- 语法 组件名称
-
一系列 代码点,它可以是 数据类型名称, 或一个能够产生 <custom-ident> 的序列。
- 语法 定义
-
一个对象,由一系列 语法组件 组成。
- 通用语法定义
-
一个特殊的语法定义,接受任何有效的令牌流。
5.4.2. 消耗语法定义
5.4.3. 消耗语法组件
从 stream 中消耗尽可能多的空格。
让 component 成为一个新的语法组件,其name和multiplier最初为空。
消耗 stream中的下一个输入代码点:
- U+003C LESS-THAN SIGN (<)
-
从 stream 中消耗数据类型名称。 如果返回一个字符串,则将 component 的 name 设置为返回值。 否则,返回失败。
- 标识符开始代码点
- U+005C REVERSE SOLIDUS (\)
-
如果流以标识符序列开头,重新消费当前输入代码点,然后从 stream 中消耗标识符序列, 并将 component 的 name 设置为返回值。 否则返回失败。
如果 component 的 name 未解析为<custom-ident>,返回失败。
- 其他任何情况
-
返回失败。
如果 component 的 name 是预乘数据类型名称, 返回 component。
如果 stream中的下一个输入代码点为U+002B PLUS SIGN (+)或U+0023 NUMBER SIGN (#), 消耗下一个输入代码点, 并将 component 的 multiplier 设置为当前输入代码点。
返回 component。
5.4.4. 消耗数据类型名称
注意:此算法假设已经从流中消耗了一个 U+003C LESS-THAN SIGN (<) 代码点。
让 name 最初为一个包含单个 U+003C LESS-THAN SIGN (<) 代码点的字符串。
重复消耗下一个输入代码点:
6. CSSOM
[[registeredPropertySet]]
插槽和 Document,
并将所有自定义属性视为未注册。6.1.
CSS CSSPropertyRule 接口
CSSPropertyRule
接口表示一个@property 规则。
[Exposed =Window ]interface CSSPropertyRule :CSSRule {readonly attribute CSSOMString name ;readonly attribute CSSOMString syntax ;readonly attribute boolean inherits ;readonly attribute CSSOMString ?initialValue ; };
name, 类型为 CSSOMString, 只读- 与@property规则相关的自定义属性名称。
syntax, 类型为 CSSOMString, 只读- 与@property相关的语法,完全按照指定内容。
inherits, 类型为 boolean, 只读- 与@property规则相关的继承描述符。
initialValue, 类型为 CSSOMString, 只读,可能为空- 与@property规则相关的初始值,可能不存在。
-
字符串
"@property"后跟一个空格(U+0020)。 -
对规则名称执行序列化标识符的结果,后跟一个空格(U+0020)。
-
字符串
"{ ",即一个左大括号(U+007B),后跟一个空格(U+0020)。 -
字符串
"syntax:",后跟一个空格(U+0020)。 -
字符串
"inherits:",后跟一个空格(U+0020)。 -
对于规则的inherits属性,根据属性值的不同,以下任意一种:
- true
-
字符串
"true"后跟一个分号(U+003B),后跟一个空格(U+0020)。 - false
-
字符串
"false"后跟一个分号(U+003B),后跟一个空格(U+0020)。
-
如果规则的initial-value存在,则执行以下子步骤:
-
字符串
"initial-value:"。 -
对规则的initial-value执行序列化CSS值,后跟一个分号(U+003B),后跟一个空格(U+0020)。
-
-
一个右大括号(U+007D)。
6.2.
CSSStyleValue
具体化
对于指定值,具体化一组组件值并返回结果。
对于计算值:
-
如果值是<length>、<integer>、<number>、<angle>、<time>、<resolution>、<percentage>或<length-percentage>;具体化一个数值并返回结果。
-
如果值是<transform-list>,具体化一个<transform-list>并返回结果。
-
如果值是一个<image>,具体化一个CSSImageValue并返回结果。
-
否则,作为CSSStyleValue具体化,其中
[[associatedProperty]]内部槽设置为property,并返回结果。
7. 示例
7.1. 示例 1: 使用自定义属性添加动画行为
< script > CSS. registerProperty({ name: "--stop-color" , syntax: "<color>" , inherits: false , initialValue: "rgba(0,0,0,0)" }); </ script > < style > . button { --stop-color : red ; background : linear-gradient( var ( --stop-color ), black ); transition : -- stop-color 1 s ; } . button : hover { --stop-color : green ; } </ style >
7.2. 示例 2: 使用 @property 注册属性
< script > CSS. paintWorklet. addModule( 'circle.js' ); </ script > < style > @ property --radius { syntax : "<length>" ; inherits : false ; initial-value : 0px ; } div { width : 100 px ; height : 100 px ; --radius : 10 px ; background : paint ( circle ); transition : -- radius 1 s ; } div : hover { --radius : 50 px ; } </ style > < div ></ div >
// circle.js registerPaint( 'circle' , class { static get inputProperties() { return [ '--radius' ]; } paint( ctx, geom, properties) { let radius= properties. get( '--radius' ). value; ctx. fillStyle= 'black' ; ctx. beginPath(); ctx. arc( geom. width/ 2 , geom. height/ 2 , radius, 0 , 2 * Math. PI); ctx. fill(); } });
8. 安全考虑
这些特性没有已知的安全问题。
9. 隐私考虑
这些特性没有已知的隐私问题。
10. 变更
10.1. 自2020年10月13日的工作草案以来的变更
/* 到2024年3月20日 */